package main; import java.util.Iterator; import java.awt.geom.Point2D; import java.awt.Point; import java.util.ArrayList; public class Player extends Creature { private NPC npcTarget; int level; int experience; Weapon weapon; Armor[] armor; ArrayList inventory; public Item[][] invSpace; public int statPoints; private int baseAttackSpeed; private int baseMoveSpeed; private int basePixelSpeed; public double attackSpeedMod; public double moveSpeedMod; public int damageMod; public int hpMod; public int mpMod; public Player(final String name, final int xOffset, final int yOffset, final int level, final int experience) { super(name, xOffset, yOffset); this.invSpace = new Item[10][8]; this.npcTarget = null; this.level = level; this.experience = experience; this.weapon = null; this.armor = new Armor[4]; for (int x = 0; x < this.armor.length; ++x) { this.armor[x] = null; } this.inventory = new ArrayList(); this.statPoints = 0; final double n = 1.0; this.moveSpeedMod = n; this.attackSpeedMod = n; final boolean damageMod = false; this.mpMod = (damageMod ? 1 : 0); this.hpMod = (damageMod ? 1 : 0); this.damageMod = (damageMod ? 1 : 0); this.basePixelSpeed = this.speed; for (int i = 0; i < this.invSpace.length; ++i) { for (int j = 0; j < this.invSpace[0].length; ++j) { this.invSpace[i][j] = null; } } } @Override public int getDamage() { if (this.weapon == null) { return super.getDamage() + this.stats[StatType.Strength.ordinal()] / 2 + this.damageMod; } return this.weapon.getDamage() + this.stats[StatType.Strength.ordinal()] / 2 + this.damageMod; } @Override public void takeDamage(final int damage) { this.hitpoints -= (int)Math.round(damage * Math.pow(0.5, this.stats[StatType.Armor.ordinal()] / 100.0)); } public int getBaseAttackSpeed() { return this.baseAttackSpeed; } public int getBaseMoveSpeed() { return this.baseMoveSpeed; } public int getBasePixelSpeed() { return this.basePixelSpeed; } public int getArmorRating() { int total = 0; for (int x = 0; x < this.armor.length; ++x) { total += this.armor[x].getArmorRating(); } return total; } public double getAttackSpeed() { final double dexMod = 1.0 + this.stats[StatType.Dexterity.ordinal()] / 50.0; double weaponAttackSpeed = 1.0; if (this.weapon != null) { weaponAttackSpeed = this.weapon.getAttackSpeed(); } return weaponAttackSpeed / this.attackSpeedMod / dexMod; } public double getMoveSpeed() { final double dexMod = 1.0 + this.stats[StatType.Dexterity.ordinal()] / 50.0; double weaponAttackSpeed = 1.0; if (this.weapon != null) { weaponAttackSpeed = this.weapon.getAttackSpeed(); } return weaponAttackSpeed / this.attackSpeedMod / dexMod; } @Override public void propagateStatChanges() { this.maxHitpoints = this.stats[StatType.Constitution.ordinal()] * 5 + this.hpMod; this.maxManapoints = this.stats[StatType.Intelligence.ordinal()] * 5 + this.mpMod; } @Override public void setModel(final Model model) { super.setModel(model); this.baseAttackSpeed = this.getModel().getAnimation(Direction.North, Action.Attacking).drawInterval; this.baseMoveSpeed = this.getModel().getAnimation(Direction.North, Action.Walking).drawInterval; } @Override public void AI_move(final Player player, final Map map) { if (this.enemyTarget != null && this.path != null && (this.path.getLast().distance(this.enemyTarget.loc) > this.loc.distance(this.path.getLast()) || this.loc.distance(this.enemyTarget.loc) * 2.0 < this.enemyTarget.loc.distance(this.path.getLast()))) { this.setEnemyTarget(this.enemyTarget, map); } } @Override public void AI_react(final Map map) { if (this.enemyTarget == null) { return; } if (this.enemyTarget.getClass() == NPC.class) { if (this.enemyTarget.intersects(this)) { this.startDialog((NPC)this.enemyTarget); this.enemyTarget = null; this.path = null; } } else { final double distance = this.loc.distance(this.enemyTarget.loc); if (this.getModel().action != Action.Attacking && this.getModel().action != Action.BeenHit && distance <= this.startRange) { this.startAttack(this.enemyTarget); } if (this.readyToAttack() && this.minRange <= distance && distance <= this.maxRange) { this.attack(this.enemyTarget, map); } } } public boolean isTalking() { return this.npcTarget != null; } public NPC getNPCTarget() { return this.npcTarget; } public void startDialog(final NPC npc) { this.npcTarget = npc; } public void endDialog() { this.npcTarget = null; } public void attack(final Creature enemy, final Map map) { this.enemyTarget.getModel().getCurrentAnimation().reset(); this.enemyTarget.getModel().action = Action.BeenHit; this.enemyTarget.takeDamage(this.getDamage()); if (this.enemyTarget.hitpoints <= 0) { this.experience += ((Enemy)enemy).xpReward; this.checkLevelUp(); final Iterator itemDrops = ((Enemy)enemy).generateDrops().iterator(); while (itemDrops.hasNext()) { this.pickUp(itemDrops.next()); } this.enemyTarget.die(); this.enemyTarget = null; this.path = null; } } public void pickUp(final Item item) { for (int i = 0; i < this.invSpace.length; ++i) { for (int j = 0; j < this.invSpace[0].length; ++j) { if (this.itemFits(item, j, i)) { for (int a = 0; a < item.getImgHeight(); ++a) { for (int b = 0; b < item.getImgWidth(); ++b) { this.invSpace[i + a][j + b] = item; } } item.invX = j; item.invY = i; this.inventory.add(item); return; } } } } public void pickUp(final Item item, final int x, final int y) { if (this.itemFits(item, x, y)) { for (int a = 0; a < item.getImgHeight(); ++a) { for (int b = 0; b < item.getImgWidth(); ++b) { this.invSpace[y + a][x + b] = item; } } item.invX = x; item.invY = y; this.inventory.add(item); } } public void drop(final Item item) { for (int a = 0; a < item.getImgHeight(); ++a) { for (int b = 0; b < item.getImgWidth(); ++b) { this.invSpace[item.invY + a][item.invX + b] = null; } } this.inventory.remove(item); } public void moveItem(final Item item, final int x, final int y) { if (this.itemFits(item, x, y)) { for (int a = 0; a < item.getImgHeight(); ++a) { for (int b = 0; b < item.getImgWidth(); ++b) { this.invSpace[item.invY + a][item.invX + b] = null; } } for (int a = 0; a < item.getImgHeight(); ++a) { for (int b = 0; b < item.getImgWidth(); ++b) { this.invSpace[y + a][x + b] = item; } } item.invX = x; item.invY = y; } } public boolean itemFits(final Item item, final int x, final int y) { if (x < 0 || x + item.imgWidth > this.invSpace[0].length) { return false; } if (y < 0 || y + item.imgHeight > this.invSpace.length) { return false; } for (int i = 0; i < item.getImgHeight(); ++i) { for (int j = 0; j < item.getImgWidth(); ++j) { if (this.invSpace[i + y][j + x] != null && this.invSpace[i + y][j + x] != item) { return false; } } } return true; } public int getMaxExperience() { return this.level * 1000; } public void checkLevelUp() { if (this.experience >= this.getMaxExperience()) { this.experience -= this.getMaxExperience(); ++this.level; this.statPoints += 5; } } public void equipWeapon(final Weapon i) { this.equipItem(i); if (this.weapon != null) { this.unequipItem(this.weapon); this.pickUp(this.weapon); } this.weapon = i; Direction[] values; for (int length = (values = Direction.values()).length, j = 0; j < length; ++j) { final Direction dir = values[j]; this.getModel().getAnimation(dir, Action.Attacking).drawInterval = (int)(this.getBaseAttackSpeed() * this.getAttackSpeed()); } } public void unequipWeapon(final Weapon i) { this.unequipItem(i); this.weapon = null; Direction[] values; for (int length = (values = Direction.values()).length, j = 0; j < length; ++j) { final Direction dir = values[j]; this.getModel().getAnimation(dir, Action.Attacking).drawInterval = (int)(this.getBaseAttackSpeed() * this.getAttackSpeed()); } } public void equipArmor(final int pos, final Armor i) { final int[] stats = this.stats; final int ordinal = StatType.Armor.ordinal(); stats[ordinal] += i.getArmorRating(); this.equipItem(i); if (this.armor[pos] != null) { final int[] stats2 = this.stats; final int ordinal2 = StatType.Armor.ordinal(); stats2[ordinal2] -= this.armor[pos].getArmorRating(); this.unequipItem(this.armor[pos]); this.pickUp(this.armor[pos]); } this.armor[pos] = i; } public void unequipArmor(final int pos, final Armor i) { final int[] stats = this.stats; final int ordinal = StatType.Armor.ordinal(); stats[ordinal] -= i.getArmorRating(); this.unequipItem(i); this.armor[pos] = null; } private void unequipItem(final Item i) { final Iterator iter = i.getEffects().iterator(); while (iter.hasNext()) { iter.next().unapply(this); } } private void equipItem(final Item i) { final Iterator iter = i.getEffects().iterator(); while (iter.hasNext()) { iter.next().apply(this); } } }