테스트

aion-server 4.8

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

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

import com.aionemu.gameserver.controllers.attack.AttackResult;
import com.aionemu.gameserver.controllers.attack.AttackStatus;
import com.aionemu.gameserver.controllers.observer.*;
import com.aionemu.gameserver.model.gameobjects.Creature;
import com.aionemu.gameserver.model.gameobjects.Item;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.skillengine.effect.AbnormalState;
import com.aionemu.gameserver.skillengine.model.Effect;
import com.aionemu.gameserver.skillengine.model.ShieldType;
import com.aionemu.gameserver.skillengine.model.Skill;

/**
 * @author ATracer, Cura
 */
public class ObserveController {

	protected final Collection<ActionObserver> observers = new CopyOnWriteArrayList<>();
	protected final List<ActionObserver> onceUsedObservers = new ArrayList<>();
	protected final Collection<AttackCalcObserver> attackCalcObservers = new CopyOnWriteArrayList<>();

	/**
	 * Once used observer add to observerController. If observer notify will be removed.
	 */
	public void attach(ActionObserver observer) {
		observer.makeOneTimeUse();
		synchronized (onceUsedObservers) {
			onceUsedObservers.add(observer);
		}
	}

	public void addObserver(ActionObserver observer) {
		observers.add(observer);
	}

	public void addAttackCalcObserver(AttackCalcObserver observer) {
		attackCalcObservers.add(observer);
	}

	public void removeObserver(ActionObserver observer) {
		if (observers.remove(observer)) {
			observer.onRemoved();
		} else {
			synchronized (onceUsedObservers) {
				if (onceUsedObservers.remove(observer))
					observer.onRemoved();
			}
		}
	}

	public void removeAttackCalcObserver(AttackCalcObserver observer) {
		attackCalcObservers.remove(observer);
	}

	public void notifyObservers(ObserverType type, Object... object) {
		List<ActionObserver> tempOnceused = Collections.emptyList();
		synchronized (onceUsedObservers) {
			if (onceUsedObservers.size() > 0) {
				tempOnceused = new ArrayList<>();
				Iterator<ActionObserver> iterator = onceUsedObservers.iterator();
				while (iterator.hasNext()) {
					ActionObserver observer = iterator.next();
					if (observer.getObserverType().matchesObserver(type)) {
						if (observer.tryUse()) {
							tempOnceused.add(observer);
							iterator.remove();
						}
					}
				}
			}
		}

		// notify outside of lock
		for (ActionObserver observer : tempOnceused) {
			notifyAction(type, observer, object);
			observer.onRemoved();
		}

		if (observers.size() > 0) {
			for (ActionObserver observer : observers) {
				if (observer.getObserverType().matchesObserver(type)) {
					notifyAction(type, observer, object);
				}
			}
		}
	}

	private void notifyAction(ObserverType type, ActionObserver observer, Object... object) {
		switch (type) {
			case ATTACK:
				observer.attack((Creature) object[0], (int) object[1]);
				break;
			case ATTACKED:
				observer.attacked((Creature) object[0], (int) object[1]);
				break;
			case DEATH:
				observer.died((Creature) object[0]);
				break;
			case EQUIP:
				observer.equip((Item) object[0], (Player) object[1]);
				break;
			case UNEQUIP:
				observer.unequip((Item) object[0], (Player) object[1]);
				break;
			case MOVE:
				observer.moved();
				break;
			case STARTSKILLCAST:
				observer.startSkillCast((Skill) object[0]);
				break;
			case ENDSKILLCAST:
				observer.endSkillCast((Skill) object[0]);
				break;
			case BOOSTSKILLCOST:
				observer.boostSkillCost((Skill) object[0]);
				break;
			case DOT_ATTACKED:
				observer.dotattacked((Creature) object[0], (Effect) object[1]);
				break;
			case ITEMUSE:
				observer.itemused((Item) object[0]);
				break;
			case ABNORMALSETTED:
				observer.abnormalsetted((AbnormalState) object[0]);
				break;
			case SUMMONRELEASE:
				observer.summonrelease();
				break;
			case SIT:
				observer.sit();
				break;
			case HP_CHANGED:
				observer.hpChanged((int) object[0]);
				break;
		}
	}

	public void notifyDeathObservers(Creature creature) {
		notifyObservers(ObserverType.DEATH, creature);
	}

	public void notifyMoveObservers() {
		notifyObservers(ObserverType.MOVE);
	}

	public void notifySitObservers() {
		notifyObservers(ObserverType.SIT);
	}

	public void notifyAttackObservers(Creature creature, int skillId) {
		notifyObservers(ObserverType.ATTACK, creature, skillId);
	}

	public void notifyAttackedObservers(Creature creature, int skillId) {
		notifyObservers(ObserverType.ATTACKED, creature, skillId);
	}

	public void notifyDotAttackedObservers(Creature creature, Effect effect) {
		notifyObservers(ObserverType.DOT_ATTACKED, creature, effect);
	}

	public void notifyStartSkillCastObservers(Skill skill) {
		notifyObservers(ObserverType.STARTSKILLCAST, skill);
	}

	public void notifyEndSkillCastObservers(Skill skill) {
		notifyObservers(ObserverType.ENDSKILLCAST, skill);
	}

	public void notifyBoostSkillCostObservers(Skill skill) {
		notifyObservers(ObserverType.BOOSTSKILLCOST, skill);
	}

	public void notifyItemEquip(Item item, Player owner) {
		notifyObservers(ObserverType.EQUIP, item, owner);
	}

	public void notifyItemUnEquip(Item item, Player owner) {
		notifyObservers(ObserverType.UNEQUIP, item, owner);
	}

	public void notifyItemuseObservers(Item item) {
		notifyObservers(ObserverType.ITEMUSE, item);
	}

	public void notifyAbnormalSettedObservers(AbnormalState state) {
		notifyObservers(ObserverType.ABNORMALSETTED, state);
	}

	public void notifySummonReleaseObservers() {
		notifyObservers(ObserverType.SUMMONRELEASE);
	}

	public void notifyHPChangeObservers(int hpValue) {
		notifyObservers(ObserverType.HP_CHANGED, hpValue);
	}

	public boolean checkAttackStatus(AttackStatus status) {
		if (attackCalcObservers.size() > 0) {
			for (AttackCalcObserver observer : attackCalcObservers) {
				if (observer.checkStatus(status)) {
					return true;
				}
			}
		}
		return false;
	}

	public boolean checkAttackerStatus(AttackStatus status) {
		if (attackCalcObservers.size() > 0) {
			for (AttackCalcObserver observer : attackCalcObservers) {
				if (observer.checkAttackerStatus(status)) {
					return true;
				}
			}
		}
		return false;
	}

	public AttackerCriticalStatus checkAttackerCriticalStatus(AttackStatus status, boolean isSkill) {
		if (attackCalcObservers.size() > 0) {
			for (AttackCalcObserver observer : attackCalcObservers) {
				AttackerCriticalStatus acStatus = observer.checkAttackerCriticalStatus(status, isSkill);
				if (acStatus.isResult()) {
					return acStatus;
				}
			}
		}
		return new AttackerCriticalStatus(false);
	}

	public void checkShieldStatus(List<AttackResult> attackList, Effect effect, Creature attacker) {
		checkShieldStatus(attackList, effect, attacker, null);
	}

	public void checkShieldStatus(List<AttackResult> attackList, Effect effect, Creature attacker, ShieldType shieldType) {
		if (attackCalcObservers.size() > 0) {
			for (AttackCalcObserver observer : attackCalcObservers) {
				if (shieldType == null || observer instanceof AttackShieldObserver && ((AttackShieldObserver) observer).getShieldType() == shieldType)
					observer.checkShield(attackList, effect, attacker);
			}
		}
	}

	public float getBasePhysicalDamageMultiplier(boolean isSkill) {
		float multiplier = 1;
		if (attackCalcObservers.size() > 0) {
			for (AttackCalcObserver observer : attackCalcObservers) {
				multiplier *= observer.getBasePhysicalDamageMultiplier(isSkill);
			}
		}
		return multiplier;
	}

	public float getBaseMagicalDamageMultiplier() {
		float multiplier = 1;
		if (attackCalcObservers.size() > 0) {
			for (AttackCalcObserver observer : attackCalcObservers) {
				multiplier *= observer.getBaseMagicalDamageMultiplier();
			}
		}
		return multiplier;
	}

	/**
	 * Clear all observers
	 */
	public void clear() {
		synchronized (onceUsedObservers) {
			onceUsedObservers.forEach(ActionObserver::onRemoved);
			onceUsedObservers.clear();
		}
		observers.forEach(ActionObserver::onRemoved);
		observers.clear();
		attackCalcObservers.clear();
	}
}

📎 첨부파일

댓글 작성 권한이 없습니다.
🏆 포인트 랭킹 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