package org.reunionemu.jreunion.game; import org.reunionemu.jreunion.game.Player.Race; import org.reunionemu.jreunion.game.npc.Mob; import org.reunionemu.jreunion.game.quests.QuestState; import org.reunionemu.jreunion.model.quests.Objective; import org.reunionemu.jreunion.server.PacketFactory.Type; import org.reunionemu.jreunion.model.Quest; import org.reunionemu.jreunion.server.Tools; import org.slf4j.LoggerFactory; /** * @author Aidamina * @license http://reunion.googlecode.com/svn/trunk/license.txt */ public abstract class LivingObject extends WorldObject { private LivingObject target; private Position targetPosition; private String name; private long hp; private long maxHp; private int level; private int dmgType; // 0-normal; 1-critical; 2-demolition; 3-super critical; 4-Explosion; public Position getTargetPosition() { return targetPosition; } public void setTargetPosition(Position targetPosition) { this.targetPosition = targetPosition; } public int getPercentageHp() { double percentageHp = this.getHp() * 100 / this.getMaxHp(); return (int) ((percentageHp < 1 && percentageHp > 0) ? 1 : percentageHp); } public void walk(Position position, boolean isRuning) { //setIsRunning(isRunning); synchronized(this) { setPosition(position); setTargetPosition(position.clone()); } getInterested().sendPacket(Type.WALK, this, position); } public int getDmgType() { return dmgType; } public void setDmgType(int dmgType) { this.dmgType = dmgType; } //players: 0-walking 1-running ; npc: 0-stoped 1-moving private boolean running; public void setIsRunning(boolean running) { this.running = running; } public boolean isRunning() { return running; } public LivingObject() { super(); } public long getHp() { return hp; } public int getLevel() { return level; } public long getMaxHp() { return maxHp; } public LivingObject getTarget() { return target; } public void loadFromReference(int id) { } public void setHp(long hp) { this.hp = Tools.between(hp, 0l, getMaxHp()); } public void setLevel(int level) { this.level = level; } public void setMaxHp(long maxHp) { this.maxHp = maxHp; } public void setTarget(LivingObject target) { this.target = target; } public String getName(){ return this.name; } public void setName(String livingObjectName){ this.name = livingObjectName; } // 1-short range melee; 2-magic; 3-summon; 4-long range melee; public int getLastAttackType(){ if (this instanceof Player) { Player player = (Player) this; // as Kailipton can use magic without a weapon, we will consider all attacks as Magic attack. if (player.getRace() == Race.KAILIPTON) { return 2; } else { Item<?> weapon = player.getEquipment().getMainHand(); if (weapon == null) { return 1; } else { if (weapon.getType() instanceof MeleeWeapon) { return 1; } else if (weapon.getType() instanceof MagicWeapon) { return 2; } else if (weapon.getType() instanceof SummonWeapon) { return 3; } else if (weapon.getType() instanceof RangedWeapon) { return 4; } } } } else if(this instanceof Pet){ return 1; } else if(this instanceof Npc){ if(((Npc<?>)this).getType() instanceof Mob){ Mob mob = (Mob)((Npc<?>)this).getType(); return mob.getAttackType(); } } return 0; } public void getsAttacked(Player player, long damage, boolean addAttack){ Npc<?> npc = null; Mob mob = null; if(this instanceof Npc){ npc = (Npc<?>)this; if(npc.getType() instanceof Mob){ mob = (Mob) npc.getType(); } } if(addAttack){ player.addAttack(damage); } /* // TODO: reimplement using the new quest system //Cursed quest Boss packet if(mob != null){ QuestState questState = player.getQuestState(); if(questState != null){ Quest quest = questState.getQuest(); if(quest instanceof ExperienceQuest){ Objective objective = quest.getObjective(npc.getType().getTypeId()); if(objective != null){ if(questState.getProgression(objective.getId()) == (objective.getAmmount()-1)){ if(!npc.isBoss()){ player.getClient().sendPacket(Type.QT, "king "+this.getEntityId()+" 1"); npc.setBoss(); } } } } } }*/ if(npc.isMutant()){ damage = (long)(damage * npc.getMutantResistance(player)); // Damage Calculation for Mutants // The Mutant which is for the player race, gets 100% resistance value // All other Mutant colors getting 25% resistance value /* float resistance = npc.getMutantResistance(player); // Value caps to prevent invincible mobs and other problems if (resistance > 0.9) { resistance = 0.9f; } if (resistance < 0.1) { resistance = 0.1f; } if (npc.getMutantType() == 1) { if (player.getRace() == Player.Race.BULKAN ) { damage = (long)(damage * resistance); } else if (player.getRace() == Player.Race.HYBRIDER ) { damage = (long)(damage * resistance); } else if (player.getRace() == Player.Race.PET ) { damage = (long)(damage * resistance); } } else if (npc.getMutantType() == 2) { if (player.getRace() == Player.Race.KAILIPTON) { damage = (long)(damage * resistance); } } else if (npc.getMutantType() == 3) { if (player.getRace() == Player.Race.AIDIA) { damage = (long)(damage * resistance); } } else if (npc.getMutantType() == 4) { if (player.getRace() == Player.Race.HUMAN) { damage = (long)(damage * resistance); } } else { // 25% of resistant value for non class specific resistance resistance = resistance / 4; if (resistance < 0.1) { resistance = 0.1f; } damage = (long)(damage * resistance); } */ } long newHp = getHp() - damage; setHp(newHp); if (this.getPercentageHp() < 1) { LoggerFactory.getLogger(LivingObject.class).info("Player "+player+" killed npc "+this); if(npc != null){ npc.kill(player); } } this.getInterested().sendPacket(Type.ATTACK_VITAL, this); } public static enum AttackType { NO_ATTACK(0), CLOSE_MELEE(1), MAGIC(2), SUMMON(3), RANGE_MELEE(4); int value; AttackType(int value){ this.value = value; } public int value(){ return value; } public static AttackType byValue(int attackTypeId){ for(AttackType attackType:AttackType.values()) { if(attackType.value()==attackTypeId){ return attackType; } } return null; } } public static enum DamageType { NO_DAMAGE(-1), NORMAL(0), CRITICAL(1), DEMOLITION(2), FIREBALL(3), LIGHTNING(4), LIGHTNINGBALL(5), STARFLARE(6); int value; DamageType(int value){ this.value = value; } public int value(){ return value; } public static DamageType byValue(int damageTypeId){ for(DamageType damageType:DamageType.values()) { if(damageType.value()==damageTypeId){ return damageType; } } return null; } } }