package com.weem.epicinventor.actor.monster;
import com.weem.epicinventor.*;
import com.weem.epicinventor.actor.*;
import com.weem.epicinventor.ai.*;
import com.weem.epicinventor.drop.*;
import com.weem.epicinventor.network.*;
import com.weem.epicinventor.placeable.*;
import com.weem.epicinventor.utility.*;
import com.weem.epicinventor.world.block.BlockManager;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.AffineTransform;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
public abstract class Monster extends Actor implements Serializable {
private static final long serialVersionUID = 10000L;
transient protected MonsterManager monsterManager;
protected DropChanceCollection dropChances;
protected AI ai;
protected String name;
protected String displayName;
protected String spawnType;
protected int maxAggroRange;
protected int touchDamage = 10;
protected int meleeDamage = 10;
protected int meleeSpeed = 1000;
protected float mapXMin, mapXMax;
protected boolean isInPanel;
protected static int levelWeights[];
protected int groundLevel;
protected boolean isDirty;
protected long nextSoundPlay;
protected int playerDamage;
protected final static int MIN_X_SPAWN = 800;
protected int placeableDamage;
protected int level;
protected boolean hideDisplayName = false;
protected float difficultyFactor = 0.50f;
public Monster(MonsterManager mm, Registry rg, String im, String st, int x, int y, int minDist, int maxDist, boolean spawnTop) {
super(mm, rg, im, x, y);
monsterManager = mm;
spawnType = st;
isStill = true;
facing = Facing.LEFT;
vertMoveMode = VertMoveMode.NOT_JUMPING;
yx = new int[2];
ycm = new int[2];
maxAggroRange = MonsterManager.mobSpawnRangeMax;
ai = new AI(registry, this);
maxFollowDistance = 5;
dropChances = new DropChanceCollection();
Point p = findSpawnNearPoint(new Point(x, y), minDist, maxDist, spawnTop);
mapX = p.x;
mapY = p.y;
groundLevel = registry.getBlockManager().getLevelByY(mapY);
if (monsterManager.doesRectContainBlocks(mapX, mapY, width, height)) {
isDirty = true;
}
determineLevel();
showGoals = monsterManager.getShowGoals();
}
private Point findSpawnNearPoint(Point p, int minDist, int maxDist, boolean spawnTop) {
int dist = Rand.getRange(minDist, maxDist);
int angle = Rand.getRange(0, 360);
Point retP = new Point(-1, -1);
int x, y, newDist;
for (int i = 0; i < 360; i += 20) {
x = (int) (dist * Math.cos(Math.toRadians(angle + i))) + p.x;
y = (int) (dist * Math.sin(Math.toRadians(angle + i))) + p.y;
if (x >= MIN_X_SPAWN && y > 0) {
if (spawnTop) {
y = monsterManager.findFloor(x);
} else {
y = monsterManager.findNextFloor(x, y, height + BlockManager.getBlockHeight() * 4);
}
newDist = (int) Math.sqrt(Math.pow(Math.abs(p.x - x), 2.0f) + Math.pow(Math.abs(p.y - y), 2.0f));
if (newDist > minDist && newDist < maxDist) {
if (!monsterManager.doesRectContainBlocks(x, y, width, height)) {
boolean touchingPlaceable = false;
Placeable placeable = registry.getPlaceableManager().getClosest(new Point(x, y));
if (placeable != null) {
if (placeable.getPerimeter().intersects(new Rectangle(x, y, 120, 120))) {
touchingPlaceable = true;
}
}
if (!touchingPlaceable) {
retP.x = x;
retP.y = y;
break;
}
}
}
}
}
return retP;
}
public void setTransient(Registry rg, MonsterManager mm) {
super.setTransient(rg, mm);
yx = new int[2];
ycm = new int[2];
registry = rg;
monsterManager = mm;
manager = mm;
ai.setTransient(this, rg);
dropChances.setTransient();
if (id == null) {
id = UUID.randomUUID().toString();
}
}
public static int getTotalForMap() {
int total = 0;
for (int i = 0; i < levelWeights.length; i++) {
total += levelWeights[i];
}
return total;
}
public int getTouchDamage() {
return touchDamage;
}
protected void determineLevel() {
int l = 1;
int playerLevel = registry.getPlayerManager().getCurrentPlayer().getLevel();
switch (groundLevel) {
case 2:
l = Rand.getRange(playerLevel - 1, playerLevel + 4);
if (l > 15) {
l = 15;
}
break;
case 3:
l = Rand.getRange(playerLevel, playerLevel + 6);
if (l > 20) {
l = 20;
}
break;
case 4:
l = Rand.getRange(playerLevel + 1, playerLevel + 8);
if (l > 25) {
l = 25;
}
break;
case 5:
l = Rand.getRange(playerLevel + 2, playerLevel + 10);
if (l > 30) {
l = 30;
}
break;
default:
l = Rand.getRange(playerLevel - 2, playerLevel + 2);
if (l > 10) {
l = 10;
}
break;
}
if (l < 1) {
l = 1;
}
level = l;
}
protected void adjustHPForLevel() {
int[] hpTable = new int[31];
hpTable[0] = 0;
hpTable[1] = 37;
hpTable[2] = 61;
hpTable[3] = 96;
hpTable[4] = 139;
hpTable[5] = 188;
hpTable[6] = 240;
hpTable[7] = 296;
hpTable[8] = 354;
hpTable[9] = 413;
hpTable[10] = 473;
hpTable[11] = 535;
hpTable[12] = 597;
hpTable[13] = 659;
hpTable[14] = 722;
hpTable[15] = 786;
hpTable[16] = 849;
hpTable[17] = 913;
hpTable[18] = 977;
hpTable[19] = 1042;
hpTable[20] = 1106;
hpTable[21] = 1171;
hpTable[22] = 1235;
hpTable[23] = 1300;
hpTable[24] = 1365;
hpTable[25] = 1430;
hpTable[26] = 1495;
hpTable[27] = 1560;
hpTable[28] = 1625;
hpTable[29] = 1691;
hpTable[30] = 1756;
if (level > 0 && level <= hpTable.length) {
totalHitPoints = hpTable[level];
} else {
totalHitPoints = hpTable[1];
}
//hp varies 10% based on difficulty rating
float variance = (float) totalHitPoints * 0.10f;
variance *= 1.00f - difficultyFactor;
totalHitPoints = (int) ((float) totalHitPoints - variance);
hitPoints = totalHitPoints;
}
protected void adjustTouchDamageForLevel() {
int[] damageTable = new int[31];
damageTable[0] = 0;
damageTable[1] = 10;
damageTable[2] = 20;
damageTable[3] = 30;
damageTable[4] = 40;
damageTable[5] = 50;
damageTable[6] = 60;
damageTable[7] = 70;
damageTable[8] = 80;
damageTable[9] = 90;
damageTable[10] = 100;
damageTable[11] = 110;
damageTable[12] = 120;
damageTable[13] = 130;
damageTable[14] = 140;
damageTable[15] = 150;
damageTable[16] = 160;
damageTable[17] = 170;
damageTable[18] = 180;
damageTable[19] = 190;
damageTable[20] = 200;
damageTable[21] = 210;
damageTable[22] = 220;
damageTable[23] = 230;
damageTable[24] = 240;
damageTable[25] = 250;
damageTable[26] = 260;
damageTable[27] = 270;
damageTable[28] = 280;
damageTable[29] = 290;
damageTable[30] = 300;
if (level > 0 && level <= damageTable.length) {
touchDamage = damageTable[level];
} else {
touchDamage = damageTable[1];
}
//damage varies 20% based on difficulty rating
float variance = (float) touchDamage * 0.20f;
variance *= 1.00f - difficultyFactor;
touchDamage = (int) ((float) touchDamage - variance);
}
protected void registerAttacker(Actor a, int d, boolean fromPlaceable) {
if (a != null && d > 0) {
if (attackers == null) {
attackers = new HashMap<Actor, Integer>();
}
if (fromPlaceable) {
lastAttacker = null;
placeableDamage += d;
} else {
lastAttacker = a;
if (attackers.containsKey(a)) {
attackers.put(a, attackers.get(a) + d);
} else {
attackers.put(a, d);
}
}
}
}
public int applyDamage(int damage, Actor a, boolean fromPlaceable) {
return applyDamage(damage, a, fromPlaceable, true);
}
public int applyDamage(int damage, Actor a, boolean fromPlaceable, boolean sound) {
if (damage <= 0) {
return 0;
}
damage -= Math.floor(getArmorPoints() / 5);
registerAttacker(a, damage, fromPlaceable);
if (damage <= 0) {
damage = 1;
}
hitPoints -= damage;
registry.getIndicatorManager().createIndicator(mapX + (width / 2), mapY + 50, "-" + Integer.toString(damage));
if (sound) {
SoundClip cl = new SoundClip(registry, "Monster/Hurt" + name + Rand.getRange(1, 2), getCenterPoint());
}
if (registry.getGameController().multiplayerMode == registry.getGameController().multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateMonster um = new UpdateMonster(this.getId());
um.mapX = this.getMapX();
um.mapY = this.getMapY();
um.action = "ApplyDamage";
um.dataInt = damage;
um.actor = a;
registry.getNetworkThread().sendData(um);
}
}
return damage;
}
protected Color getColorBasedOnPlayerLevel(int l) {
if (level == -1) {
return Color.MAGENTA;
} else if (level < l - 2) {
return Color.LIGHT_GRAY;
} else if (level >= l - 2 && level < l) {
return Color.GREEN;
} else if (level == l) {
return Color.YELLOW;
} else if (level > l && level <= l + 2) {
return Color.ORANGE;
} else if (level > l + 2) {
return Color.RED;
}
return Color.RED;
}
public int getXMoveSize() {
return xMoveSize;
}
public void setXMoveSize(int s) {
xMoveSize = s;
}
public String getSpawnType() {
return spawnType;
}
public int getPlayerDamage() {
return playerDamage;
}
public int getMaxAggroRange() {
return maxAggroRange;
}
public String getName() {
return name;
}
public boolean isDirty() {
return isDirty;
}
public boolean isAttacking() {
if (actionMode == ActionMode.ATTACKING) {
return true;
} else {
return false;
}
}
public boolean getIsInPanel() {
return isInPanel;
}
public void setPlayerDamage(int d) {
playerDamage = 0;
}
public Point getNewXY(int mapWidth, int l) {
Point p = new Point(0, 0);
p.x = Rand.getRange(1000, mapWidth);
int diff = (registry.getBlockManager().getLevelTop(l) - registry.getBlockManager().getLevelBottom(l));
p.y = Rand.getRange(registry.getBlockManager().getLevelBottom(l) + diff / 4,
registry.getBlockManager().getLevelTop(l));
p.y = monsterManager.findNextFloor(p.x, p.y, height + BlockManager.getBlockHeight() * 4) + BlockManager.getBlockHeight() * 2;
return p;
}
protected int randomX(int mapWidth) {
int rangeMin = (int) (mapXMin * mapWidth);
int rangeMax = (int) (mapXMax * mapWidth);
return Rand.getRange(rangeMin, rangeMax);
}
public Damage getMonsterTouchDamage(Rectangle r) {
return getMonsterTouchDamage(r, 0);
}
public Damage getMonsterTouchDamage(Rectangle r, int x) {
if (hitPoints > 0) {
if (spriteRect != null && r != null) {
if (spriteRect.intersects(r)) {
playerDamage += touchDamage;
return new Damage(this, touchDamage);
}
}
}
return null;
}
public boolean isMoving() {
if (isStill && vertMoveMode == VertMoveMode.NOT_JUMPING) {
return false;
} else {
return true;
}
}
public boolean isAttacking(Player p) {
boolean ret = false;
Goal g = ai.getCurrentGoal();
if (g != null) {
if (g.getGoalType().equals("GoalAttackPlayer")) {
Player player = ((GoalAttackPlayer) g).getPlayerToAttack(this);
if (player == p) {
ret = true;
}
}
}
return ret;
}
public void stopJump() {
if (vertMoveMode == VertMoveMode.JUMPING) {
vertMoveMode = VertMoveMode.FALLING;
}
}
public void stopAscend() {
if (vertMoveMode == VertMoveMode.FLYING) {
vertMoveMode = VertMoveMode.FALLING;
}
}
@Override
public void attack() {
if (attackRefreshTimerEnd < System.currentTimeMillis()) {
if (actionMode != ActionMode.ATTACKING) {
actionMode = ActionMode.ATTACKING;
}
attackRefreshTimerStart = System.currentTimeMillis();
attackRefreshTimerEnd = System.currentTimeMillis() + meleeSpeed;
attackRect = new Rectangle(mapX + (width / 2), mapY, (width / 2) + attackRange, height);
if (facing == Facing.LEFT) {
attackRect = new Rectangle(mapX - attackRange, mapY, (width / 2) + attackRange, height);
}
monsterManager.monsterAttackPlaceable(this, attackRect, meleeDamage);
}
}
public void stopAttack() {
actionMode = ActionMode.NONE;
}
public int getXPByPlayer(Actor a) {
int total = 0;
int player = 0;
//figure out the total damage and the damage form the given player
if (attackers != null) {
try {
for (Actor key : attackers.keySet()) {
int value = attackers.get(key);
total += value;
if (a == key) {
player += value;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify attackers while iterating
}
}
player -= placeableDamage;
if (total > 0 && player > 0) {
float totalXP = (float) getXPTotalValue(a);
return (int) (((float) player / (float) total) * totalXP);
}
return 0;
}
public int getXPTotalValue(Actor a) {
int[] xpTable = new int[31];
xpTable[0] = 0;
xpTable[1] = 23;
xpTable[2] = 32;
xpTable[3] = 41;
xpTable[4] = 52;
xpTable[5] = 65;
xpTable[6] = 79;
xpTable[7] = 96;
xpTable[8] = 114;
xpTable[9] = 135;
xpTable[10] = 157;
xpTable[11] = 181;
xpTable[12] = 206;
xpTable[13] = 234;
xpTable[14] = 263;
xpTable[15] = 295;
xpTable[16] = 328;
xpTable[17] = 362;
xpTable[18] = 399;
xpTable[19] = 438;
xpTable[20] = 478;
xpTable[21] = 520;
xpTable[22] = 564;
xpTable[23] = 610;
xpTable[24] = 657;
xpTable[25] = 707;
xpTable[26] = 758;
xpTable[27] = 811;
xpTable[28] = 866;
xpTable[29] = 923;
xpTable[30] = 981;
if (level > 0 && level <= xpTable.length) {
//xp varies 10% based on difficulty rating
float variance = (float) xpTable[level] * 0.10f;
variance *= 1.00f - difficultyFactor;
return (int) ((float) xpTable[level] - variance);
} else {
return 0;
}
}
public void setHitPoints(int hp) {
hitPoints = hp;
}
@Override
public void update() {
super.update();
debugInfo = "";
if (isActive && isAnimating) {
if (animationFrameUpdateTime <= registry.currentTime) {
currentAnimationFrame++;
if (currentAnimationFrame >= numAnimationFrames) {
currentAnimationFrame = 0;
}
animationFrameUpdateTime = registry.currentTime + animationFrameDuration;
}
}
if (hitPoints > 0) {
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
if (knockBackX > 0) {
mapX += checkCollide(knockBackX);
} else if (knockBackX < 0) {
mapX -= checkCollide(knockBackX);
} else {
if (registry.getGameController().multiplayerMode == registry.getGameController().multiplayerMode.CLIENT) {
ai.process(true);
} else {
ai.process();
}
if (ai.getChanged()) {
ai.setChanged(false);
if (registry.getGameController().multiplayerMode == registry.getGameController().multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateMonster um = new UpdateMonster(this.getId());
um.mapX = this.getMapX();
um.mapY = this.getMapY();
um.previousGoal = ai.getPreviousGoal();
um.currentGoal = ai.getCurrentGoal();
registry.getNetworkThread().sendData(um);
}
}
}
}
}
if (monsterManager.getSelectedMob() == this) {
registry.setPortraitImage("Mob" + name);
registry.setPortraitHPCurrent(hitPoints);
registry.setPortraitHP(totalHitPoints);
registry.setPortraitAttack(touchDamage);
registry.getHUDManager().showPortrait(true);
} else if (monsterManager.getSelectedMob() == null) {
Point mousePos = new Point(monsterManager.panelToMapX(registry.getMousePosition().x), monsterManager.panelToMapY(registry.getMousePosition().y));
if (this.isInside(mousePos) && !this.getIsHiding()) {
registry.setPortraitImage("Mob" + name);
registry.setPortraitHPCurrent(hitPoints);
registry.setPortraitHP(totalHitPoints);
registry.setPortraitAttack(touchDamage);
registry.getHUDManager().showPortrait(true);
}
}
} else {
if (registry.getGameController().multiplayerMode == registry.getGameController().multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateMonster um = new UpdateMonster(this.getId());
um.mapX = this.getMapX();
um.mapY = this.getMapY();
um.action = "Die";
registry.getNetworkThread().sendData(um);
}
}
SoundClip cl = new SoundClip(registry, "Monster/Die" + name, getCenterPoint());
isDead = true;
ai.terminate();
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
ArrayList<Drop> drops = dropChances.generateDrops();
if (drops.size() > 0) {
monsterManager.dropLoot(this, mapX + (width / 2), mapY + 32, drops);
}
monsterManager.giveXP(this);
}
BufferedImage im = registry.getImageLoader().getImage(image);
if (facing == Facing.LEFT) {
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-width, 0);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
BufferedImage imLeft = op.filter(im, null);
if (imLeft != null) {
registry.getPixelizeManager().pixelize(imLeft, mapX, mapY);
}
} else {
registry.getPixelizeManager().pixelize(im, mapX, mapY);
}
}
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
if (vertMoveMode == VertMoveMode.JUMPING) {
updateJumping();
} else if (vertMoveMode == VertMoveMode.FLYING) {
updateAscending();
} else if (vertMoveMode == VertMoveMode.FALLING) {
updateFalling();
}
mapX = monsterManager.checkMapX(mapX, width);
mapY = monsterManager.checkMapY(mapY, height);
}
Player p = registry.getPlayerManager().getCurrentPlayer();
if (spriteRect.intersects(manager.getPanelRect())) {
isInPanel = true;
} else {
isInPanel = false;
}
/*if (p != null) {
if (mapX >= (p.getMapX() - (monsterManager.getPWidth() / 2))
&& mapX <= (p.getMapX() + (monsterManager.getPWidth() / 2))
&& mapY >= (p.getMapY() - (monsterManager.getPHeight() / 2))
&& mapY <= (p.getMapY() + (monsterManager.getPHeight() / 2))) {
isInPanel = true;
} else {
isInPanel = false;
}
} else {
isInPanel = true;
}*/
//debugInfo = Boolean.toString(isInPanel)
//showGoals = true;
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
if (vertMoveMode != VertMoveMode.FALLING) {
checkIfFalling();
}
}
updateImage();
}
protected boolean isInside(Point p) {
if (p.x >= mapX
&& p.x <= (mapX + width)
&& p.y >= mapY
&& p.y <= (mapY + height)) {
return true;
}
return false;
}
public void updateLong() {
if (isPoisoned) {
applyDamage(1, null, false, false);
}
if (registry.getClosestPlayer(getCenterPoint(), MonsterManager.mobSpawnRangeMin * 2) == null) {
Point p = getCenterPoint();
if (p.x > 0 && p.y > 0) {
if (!registry.getPlaceableManager().isPlaceableWithin(getCenterPoint(), MonsterManager.mobSpawnRangeMin * 2)) {
isDirty = true;
}
}
}
if (nextSoundPlay <= registry.currentTime) {
SoundClip cl = new SoundClip(registry, "Monster/Ambient" + name, getCenterPoint());
nextSoundPlay = registry.currentTime + Rand.getRange(10000, 15000);
if (name.equals("ZombieWalrus") && cl.getWasHeard()) {
loopImage("Monsters/" + name + "/Attacking", 0.50);
monsterManager.shakeCamera(500, 10);
}
}
}
public int getMaxShootRange() {
return 0;
}
public int getMaxLungeRange() {
return 0;
}
public void shoot(Point targetPoint) {
}
@Override
public void render(Graphics g) {
if (shouldRender) {
int statusCount = 0;
int statusX = 0;
int statusNewXPos = 0;
BufferedImage im;
if (isAnimating) {
im = registry.getImageLoader().getImage(image, currentAnimationFrame);
} else {
im = registry.getImageLoader().getImage(image);
}
int xPos = monsterManager.mapToPanelX(mapX);
int yPos = monsterManager.mapToPanelY(mapY);
//flip the yPos since drawing happens top down versus bottom up
yPos = monsterManager.getPHeight() - yPos;
//subtract the height since points are bottom left and drawing starts from top left
yPos -= height;
if (im != null) {
if (facing == Facing.LEFT) {
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-width, 0);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
BufferedImage imLeft = op.filter(im, null);
if (imLeft != null) {
g.drawImage(imLeft, xPos, yPos, null);
}
} else {
g.drawImage(im, xPos, yPos, null);
}
}
//render statuses
if (statusFear) {
statusCount++;
}
if (statusHeal) {
statusCount++;
}
if (statusPoison) {
statusCount++;
}
if (statusSlowed) {
statusCount++;
}
if (statusCount > 0) {
int totalWidth = (statusCount * STATUS_WIDTH) + ((statusCount - 1) * STATUS_SPACING);
statusX = getCenterPoint().x - (totalWidth / 2);
int i = 0;
if (statusFear) {
statusNewXPos = statusX + (i * STATUS_WIDTH) + (i * STATUS_SPACING);
xPos = manager.mapToPanelX(statusNewXPos);
yPos = manager.mapToPanelY(mapY + 50);
//flip the yPos since drawing happens top down versus bottom up
yPos = manager.getPHeight() - yPos;
//subtract the height since points are bottom left and drawing starts from top left
yPos -= height;
im = registry.getImageLoader().getImage("Effects/Fear");
if (im != null) {
g.drawImage(im, xPos, yPos, null);
}
i++;
}
if (statusHeal) {
statusNewXPos = statusX + (i * STATUS_WIDTH) + (i * STATUS_SPACING);
xPos = manager.mapToPanelX(statusNewXPos);
yPos = manager.mapToPanelY(mapY + 50);
//flip the yPos since drawing happens top down versus bottom up
yPos = manager.getPHeight() - yPos;
//subtract the height since points are bottom left and drawing starts from top left
yPos -= height;
im = registry.getImageLoader().getImage("Effects/Heal");
if (im != null) {
g.drawImage(im, xPos, yPos, null);
}
i++;
}
if (statusPoison) {
statusNewXPos = statusX + (i * STATUS_WIDTH) + (i * STATUS_SPACING);
xPos = manager.mapToPanelX(statusNewXPos);
yPos = manager.mapToPanelY(mapY + 50);
//flip the yPos since drawing happens top down versus bottom up
yPos = manager.getPHeight() - yPos;
//subtract the height since points are bottom left and drawing starts from top left
yPos -= height;
im = registry.getImageLoader().getImage("Effects/Poison");
if (im != null) {
g.drawImage(im, xPos, yPos, null);
}
i++;
}
if (statusSlowed) {
statusNewXPos = statusX + (i * STATUS_WIDTH) + (i * STATUS_SPACING);
xPos = manager.mapToPanelX(statusNewXPos);
yPos = manager.mapToPanelY(mapY + 50);
//flip the yPos since drawing happens top down versus bottom up
yPos = manager.getPHeight() - yPos;
//subtract the height since points are bottom left and drawing starts from top left
yPos -= height;
im = registry.getImageLoader().getImage("Effects/Slowed");
if (im != null) {
g.drawImage(im, xPos, yPos, null);
}
i++;
}
}
if (hideDisplayName == false) {
/*
* xPos = manager.mapToPanelX(this.getCenterPoint().x - 81);
* yPos = manager.mapToPanelY(mapY + height);
*
* //flip the yPos since drawing happens top down versus bottom
* up yPos = manager.getPHeight() - yPos;
*
* //subtract the height since points are bottom left and
* drawing starts from top left yPos -= height;
*
* im = registry.getImageLoader().getImage("Misc/NameBG"); if
* (im != null) { g.drawImage(im, xPos, yPos, null); }
*/
Font textFont = new Font("SansSerif", Font.BOLD, 14);
g.setFont(textFont);
FontMetrics fm = g.getFontMetrics();
int messageWidth = fm.stringWidth(displayName + " (" + level + ")");
xPos = monsterManager.mapToPanelX((int) mapX + (width / 2) - (messageWidth / 2));
yPos = monsterManager.mapToPanelY((int) mapY + height);
yPos = monsterManager.getPHeight() - yPos;
if (level == -1) {
registry.ghettoOutline(g, Color.BLACK, displayName + " (?)", xPos, yPos);
g.setColor(getColorBasedOnPlayerLevel(registry.getPlayerManager().getCurrentPlayer().getLevel()));
g.drawString(displayName + " (?)", xPos, yPos);
} else {
registry.ghettoOutline(g, Color.BLACK, displayName + " (" + level + ")", xPos, yPos);
PlayerManager playerManager = registry.getPlayerManager();
if (playerManager != null) {
Player p = registry.getPlayerManager().getCurrentPlayer();
if (p != null) {
g.setColor(getColorBasedOnPlayerLevel(p.getLevel()));
g.drawString(displayName + " (" + level + ")", xPos, yPos);
}
}
}
}
if (hitPoints < totalHitPoints) {
float percentage;
int x = mapX + (width / 2);
int y = mapY + height;
percentage = ((float) hitPoints / (float) totalHitPoints) * 100;
monsterManager.displayHP(g,
x,
y,
(int) percentage);
}
if (monsterManager.getSelectedMob() == this) {
xPos = manager.mapToPanelX(mapX + (baseWidth / 2) + baseOffset - 12);
yPos = manager.mapToPanelY(mapY);
//flip the yPos since drawing happens top down versus bottom up
yPos = manager.getPHeight() - yPos;
im = registry.getImageLoader().getImage("Monsters/Selected");
if (im != null) {
g.drawImage(im, xPos, yPos, null);
}
}
super.render(g);
}
}
@Override
protected void updateImage() {
if (vertMoveMode == VertMoveMode.JUMPING) {
setImage("Monsters/" + name + "/Jumping");
} else if (vertMoveMode == VertMoveMode.FLYING) {
loopImage("Monsters/" + name + "/Flapping");
} else if (vertMoveMode == VertMoveMode.FALLING) {
loopImage("Monsters/" + name + "/Falling");
} else {
if (this.isAttacking()) {
loopImage("Monsters/" + name + "/Attacking");
} else if (isStill) {
setImage("Monsters/" + name + "/Standing");
} else {
loopImage("Monsters/" + name + "/Walking");
}
}
}
public UDPMonster createUpdate() {
UDPMonster udpUpdate = new UDPMonster(id);
udpUpdate.mapX = mapX;
udpUpdate.lastMapY = lastMapY;
udpUpdate.mapY = mapY;
udpUpdate.width = width;
udpUpdate.height = height;
udpUpdate.xMoveSize = xMoveSize;
udpUpdate.actionMode = actionMode;
udpUpdate.vertMoveMode = vertMoveMode;
udpUpdate.facing = facing;
udpUpdate.jumpSize = jumpSize;
udpUpdate.ascendOriginalSize = ascendOriginalSize;
udpUpdate.ascendSize = ascendSize;
udpUpdate.ascendCount = ascendCount;
udpUpdate.ascendMax = ascendMax;
udpUpdate.fallSize = fallSize;
udpUpdate.isStill = isStill;
udpUpdate.isTryingToMove = isTryingToMove;
udpUpdate.startJumpSize = startJumpSize;
udpUpdate.maxFallSize = maxFallSize;
udpUpdate.gravity = gravity;
udpUpdate.totalFall = totalFall;
udpUpdate.completeFall = completeFall;
udpUpdate.totalHitPoints = totalHitPoints;
udpUpdate.hitPoints = hitPoints;
udpUpdate.totalArmorPoints = totalArmorPoints;
udpUpdate.armorPoints = armorPoints;
udpUpdate.knockBackX = knockBackX;
udpUpdate.isDead = isDead;
udpUpdate.touchDamage = touchDamage;
udpUpdate.meleeDamage = meleeDamage;
udpUpdate.meleeSpeed = meleeSpeed;
udpUpdate.mapXMin = mapXMin;
udpUpdate.mapXMax = mapXMax;
udpUpdate.groundLevel = groundLevel;
udpUpdate.isDirty = isDirty;
udpUpdate.playerDamage = playerDamage;
udpUpdate.placeableDamage = placeableDamage;
udpUpdate.level = level;
return udpUpdate;
}
public void processUpdate(UDPMonster udpUpdate) {
mapX = udpUpdate.mapX;
lastMapY = udpUpdate.lastMapY;
mapY = udpUpdate.mapY;
width = udpUpdate.width;
height = udpUpdate.height;
xMoveSize = udpUpdate.xMoveSize;
actionMode = udpUpdate.actionMode;
vertMoveMode = udpUpdate.vertMoveMode;
facing = udpUpdate.facing;
jumpSize = udpUpdate.jumpSize;
ascendOriginalSize = udpUpdate.ascendOriginalSize;
ascendSize = udpUpdate.ascendSize;
ascendCount = udpUpdate.ascendCount;
ascendMax = udpUpdate.ascendMax;
fallSize = udpUpdate.fallSize;
isStill = udpUpdate.isStill;
isTryingToMove = udpUpdate.isTryingToMove;
startJumpSize = udpUpdate.startJumpSize;
maxFallSize = udpUpdate.maxFallSize;
gravity = udpUpdate.gravity;
totalFall = udpUpdate.totalFall;
completeFall = udpUpdate.completeFall;
totalHitPoints = udpUpdate.totalHitPoints;
hitPoints = udpUpdate.hitPoints;
totalArmorPoints = udpUpdate.totalArmorPoints;
armorPoints = udpUpdate.armorPoints;
knockBackX = udpUpdate.knockBackX;
isDead = udpUpdate.isDead;
touchDamage = udpUpdate.touchDamage;
meleeDamage = udpUpdate.meleeDamage;
meleeSpeed = udpUpdate.meleeSpeed;
mapXMin = udpUpdate.mapXMin;
mapXMax = udpUpdate.mapXMax;
groundLevel = udpUpdate.groundLevel;
isDirty = udpUpdate.isDirty;
playerDamage = udpUpdate.playerDamage;
placeableDamage = udpUpdate.placeableDamage;
level = udpUpdate.level;
}
private void readObject(ObjectInputStream aInputStream) throws Exception {
aInputStream.defaultReadObject();
}
private void writeObject(ObjectOutputStream aOutputStream) throws Exception {
aOutputStream.defaultWriteObject();
}
}