테스트

aion-server 4.8

Gitteol
최고관리자 · 1 · 💬 0 클론/새로받기
 4.8 61f661d · 1 commits 새로받기(Pull)
game-server/src/com/aionemu/gameserver/skillengine/properties/TargetRangeProperty.java
package com.aionemu.gameserver.skillengine.properties;

import java.util.List;

import com.aionemu.gameserver.configs.main.GeoDataConfig;
import com.aionemu.gameserver.model.actions.PlayerMode;
import com.aionemu.gameserver.model.gameobjects.Creature;
import com.aionemu.gameserver.model.gameobjects.Summon;
import com.aionemu.gameserver.model.gameobjects.Trap;
import com.aionemu.gameserver.model.gameobjects.VisibleObject;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.gameobjects.state.CreatureVisualState;
import com.aionemu.gameserver.model.team.TeamMember;
import com.aionemu.gameserver.model.team.TemporaryPlayerTeam;
import com.aionemu.gameserver.model.templates.zone.ZoneType;
import com.aionemu.gameserver.skillengine.model.SkillTemplate;
import com.aionemu.gameserver.utils.PositionUtil;
import com.aionemu.gameserver.world.geo.GeoService;
import com.aionemu.gameserver.world.zone.ZoneInstance;

/**
 * @author ATracer, Yeats, Neon
 */
public class TargetRangeProperty {

	public static boolean set(Properties properties, Properties.ValidationResult result, Creature skillEffector, SkillTemplate skillTemplate, float x,
		float y, float z) {
		TargetRangeAttribute value = properties.getTargetType();
		int distanceToTarget = properties.getTargetDistance();
		int effectiveRange = skillEffector instanceof Trap ? skillEffector.getGameStats().getAttackRange().getCurrent() : properties.getEffectiveRange();
		int ineffectiveRange = properties.getIneffectiveRange();

		final List<Creature> effectedList = result.getTargets();
		switch (value) {
			case ONLYONE:
				break;
			case AREA:
				int altitude = properties.getEffectiveAltitude() != 0 ? properties.getEffectiveAltitude() : 1;
				Creature firstTarget = result.getFirstTarget();

				if (firstTarget == null)
					return false;

				// Create a sorted map of the objects in knownlist
				// and filter them properly
				for (VisibleObject nextCreature : firstTarget.getKnownList().getKnownObjects().values()) {
					if (!(nextCreature instanceof Creature creature))
						continue;
					if (!checkCommonRequirements(creature, skillTemplate))
						continue;

					// if (nextCreature instanceof Kisk && isInsideDisablePvpZone(creature)
					// continue;

					if (Math.abs(firstTarget.getZ() - nextCreature.getZ()) > altitude
						|| ((nextCreature instanceof Player) && ((Player) nextCreature).isInPlayerMode(PlayerMode.WINDSTREAM))) {
						continue;
					}

					// TODO this is a temporary hack for traps
					if (skillEffector instanceof Trap && ((Trap) skillEffector).getCreator() == nextCreature)
						continue;

					if (properties.getFirstTarget() == FirstTargetAttribute.POINT) {
						if (PositionUtil.isInRange(x, y, z, nextCreature.getX(), nextCreature.getY(), nextCreature.getZ(),
							effectiveRange)) {
							result.getTargets().add(creature);
						}
					} else if (properties.getEffectiveAngle() > 0) {
						if (nextCreature.equals(skillEffector))
							continue;
						// for target_range_area_type = firestorm
						if (properties.getEffectiveAngle() < 360) {
							float angle = properties.getEffectiveAngle() / 2f; // e.g. 60 degrees (always positive) = 30 degrees in positive and negative direction
							if (properties.getDirection() == AreaDirections.BACK) {
								if (!PositionUtil.isBehind(nextCreature, skillEffector, angle))
									continue;
							} else {
								if (!PositionUtil.isInFrontOf(nextCreature, skillEffector, angle))
									continue;
							}
						}
						if (!PositionUtil.isInRange(skillEffector, nextCreature, properties.getEffectiveDist(), false))
							continue;
						if (!shouldAffectTarget(nextCreature, result.getFirstTarget(), skillTemplate))
							continue;
						result.getTargets().add(creature);
					} else if (properties.getEffectiveDist() > 0) {
						// Lightning bolt
						if (PositionUtil.isInsideAttackCylinder(skillEffector, nextCreature, properties.getEffectiveDist(), (effectiveRange / 2f), properties.getDirection())) {
							if (!shouldAffectTarget(nextCreature, result.getFirstTarget(), skillTemplate))
								continue;
							result.getTargets().add(creature);
						}
					} else if (PositionUtil.isInRange(firstTarget, nextCreature, effectiveRange, false)) {
						// for target_range_area_type = fireball
						if (ineffectiveRange > 0 && PositionUtil.isInRange(firstTarget, nextCreature, ineffectiveRange, false))
							continue;
						if (!shouldAffectTarget(nextCreature, result.getFirstTarget(), skillTemplate))
							continue;
						result.getTargets().add(creature);
					}
				}

				break;
			case PARTY:
			case PARTY_WITHPET:
				// if only firsttarget will be affected (e.g. Bodyguard), we don't need to evaluate the whole group
				if (properties.getTargetMaxCount() == 1 && properties.getFirstTarget() != FirstTargetAttribute.POINT)
					break;
				if (skillEffector instanceof Player effector) {
					TemporaryPlayerTeam<? extends TeamMember<Player>> team;
					if (value == TargetRangeAttribute.PARTY_WITHPET) {
						team = effector.getCurrentTeam(); // group or whole alliance
						tryAddSummon(effector.getSummon(), result, skillTemplate, effectedList);
					} else {
						team = effector.getCurrentGroup(); // group or alliance group (max 6 targets)
					}
					if (team != null) {
						effectedList.clear();
						for (Player member : team.getMembers()) {
							if (!member.isOnline())
								continue;
							if (!checkCommonRequirements(member, skillTemplate))
								continue;
							if (PositionUtil.isInRange(effector, member, effectiveRange, false)) {
								if (shouldAffectTarget(member, result.getFirstTarget(), skillTemplate))
									effectedList.add(member);
								if (value == TargetRangeAttribute.PARTY_WITHPET)
									tryAddSummon(member.getSummon(), result, skillTemplate, effectedList);
							}
						}
					}
				}
				break;
			case POINT:
				for (VisibleObject nextCreature : skillEffector.getKnownList().getKnownObjects().values()) {
					if (!(nextCreature instanceof Creature creature))
						continue;
					if (!checkCommonRequirements(creature, skillTemplate))
						continue;

					if (nextCreature instanceof Trap trap && !trap.getMaster().isEnemy(skillEffector))
						continue;

					if (!PositionUtil.isInRange(nextCreature, x, y, z, distanceToTarget + 1))
						continue;
					if (shouldAffectTarget(nextCreature, result.getFirstTarget(), skillTemplate))
						effectedList.add(creature);
				}
				break;
		}

		return true;
	}

	private static boolean checkCommonRequirements(Creature creature, SkillTemplate skillTemplate) {
		if (skillTemplate.hasResurrectEffect()) {
			if (!creature.isDead())
				return false;
		} else {
			if (creature.isDead())
				return false;
		}

		// blinking state means protection is active (no interaction with creature is possible)
		if (creature.isInVisualState(CreatureVisualState.BLINKING))
			return false;

		return true;
	}

	@SuppressWarnings("unused")
	private static boolean isInsideDisablePvpZone(Creature creature) {
		if (creature.isInsideZoneType(ZoneType.PVP)) {
			for (ZoneInstance zone : creature.findZones()) {
				if (zone.getZoneTemplate().getFlags() == 0)
					return true;
			}
		}
		return false;
	}

	private static boolean shouldAffectTarget(VisibleObject object, Creature firstTarget, SkillTemplate skillTemplate) {
		// If creature is at least 2 meters above the terrain, ground skill cannot be applied
		if (GeoDataConfig.GEO_ENABLE) {
			if (skillTemplate.isGroundSkill()) {
				float geoZ = GeoService.getInstance().getZ(object, object.getZ() + 2, object.getZ() - 100);
				if (!Float.isNaN(geoZ) && object.getZ() - geoZ > 2f)
					return false;
			}
			return GeoService.getInstance().canSee(firstTarget, object);
		}
		return true;
	}

	private static void tryAddSummon(Summon summon, Properties.ValidationResult result, SkillTemplate skillTemplate, List<Creature> effectedList) {
		if (summon != null && shouldAffectTarget(summon, result.getFirstTarget(), skillTemplate))
			effectedList.add(summon);
	}
}

📎 첨부파일

댓글 작성 권한이 없습니다.
🏆 포인트 랭킹 TOP 10
순위 닉네임 포인트
1 no_profile 타키야겐지쪽지보내기 자기소개 아이디로 검색 전체게시물 102,949
2 no_profile 동가리쪽지보내기 자기소개 아이디로 검색 전체게시물 63,733
3 no_profile 라프텔쪽지보내기 자기소개 아이디로 검색 전체게시물 51,771
4 no_profile 불멸의행복쪽지보내기 자기소개 아이디로 검색 전체게시물 36,923
5 서번트쪽지보내기 자기소개 아이디로 검색 전체게시물 35,011
6 no_profile 닥터스쪽지보내기 자기소개 아이디로 검색 전체게시물 29,470
7 no_profile 검은고양이쪽지보내기 자기소개 아이디로 검색 전체게시물 29,077
8 no_profile Revolution쪽지보내기 자기소개 아이디로 검색 전체게시물 28,199
9 no_profile 보거스쪽지보내기 자기소개 아이디로 검색 전체게시물 26,731
10 no_profile 호롤롤로쪽지보내기 자기소개 아이디로 검색 전체게시물 17,020
알림 0