package com.weem.epicinventor.actor.monster;
import com.weem.epicinventor.actor.*;
import com.weem.epicinventor.drop.*;
import com.weem.epicinventor.network.*;
import com.weem.epicinventor.particle.*;
import com.weem.epicinventor.placeable.*;
import com.weem.epicinventor.projectile.*;
import com.weem.epicinventor.utility.*;
import com.weem.epicinventor.*;
import java.awt.*;
import java.awt.geom.Arc2D;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
public class MonsterManager extends Manager implements Serializable, Cloneable {
protected static final long serialVersionUID = 10000L;
private HashMap<String, Monster> monsters;
public static int mobSpawnRangeMin = 1600;
public static int mobSpawnRangeMax = 2400;
private static double spawnRatioDiff = 0.02f;
transient private static HashMap<String, Integer> spawnCoolDowns;
private boolean showRect;
private boolean showGoals;
transient private long nextBossOrcSpawn = 0;
transient private long nextSnailRiderSpawn = 0;
transient private boolean transmitting;
transient private Monster selectedMob = null;
public enum MonsterType {
AggressiveSnake,
BossOrc,
LionFly,
Orc,
Pig,
Porcupine,
RedOrc,
RockMonster,
Snail,
SnailRider,
Snake,
SpiderWorm,
ZombieWalrus
}
public MonsterManager(GameController gc, Registry rg) {
super(gc, rg);
monsters = new HashMap<String, Monster>();
spawnCoolDowns = new HashMap<String, Integer>();
}
@Override
public void setTransient(Registry rg) {
super.setTransient(rg);
spawnCoolDowns = new HashMap<String, Integer>();
try {
for (String key : monsters.keySet()) {
Monster monster = (Monster) monsters.get(key);
monster.setTransient(rg, this);
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public void giveXP(Monster m) {
gameController.giveXP(m);
}
public void registerMonster(Monster m) {
if (!monsters.containsKey(m.getId())) {
monsters.put(m.getId(), m);
}
}
public Monster getMonsterById(String id) {
if (monsters.containsKey(id)) {
Monster monster = monsters.get(id);
return monster;
} else {
return null;
}
}
public void generatePlants() {
int passes = 0;
int blueThornCount = 0;
int vineThornCount = 0;
do {
blueThornCount = this.getCountByType("BlueThorn");
vineThornCount = this.getCountByType("VineThorn");
spawnPlants();
Monster monster = null;
ArrayList deadMonsters = new ArrayList();
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster != null) {
monster.update();
if (monster.getIsDead()) {
deadMonsters.add(key);
}
}
}
if (deadMonsters.size() > 0) {
for (int i = 0; i < deadMonsters.size(); i++) {
//EIError.debugMsg((String) deadMonsters.get(i));
monsters.remove((String) deadMonsters.get(i));
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
passes++;
} while ((blueThornCount < 200 || vineThornCount < 200) && passes < 50);
int g = 1;
}
private void spawnPlants() {
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
//Blue Thorns
int blueThornCount = this.getCountByType("BlueThorn");
if (blueThornCount < 200) {
for (int i = 0; i < 200 - blueThornCount; i++) {
boolean canSpawn = true;
int level = Rand.getRange(1, 3);
Point vinePosition = new Point();
vinePosition.x = Rand.getRange(1, gameController.getMapWidth());
vinePosition.y = Rand.getRange(registry.getBlockManager().getLevelBottom(level),
registry.getBlockManager().getLevelTop(level));
vinePosition.y = this.findNextFloor(vinePosition.x, vinePosition.y, 60);
if (this.doesRectContainBlocks(vinePosition.x, vinePosition.y + 100, 17, 16)) {
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getName().equals("BlueThorn") || monster.getName().equals("VineThorn")) {
double distance = vinePosition.distance(monster.getCenterPoint());
if (distance < 750) {
canSpawn = false;
break;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
if (canSpawn) {
spawn("BlueThorn", "Roaming", vinePosition.x, vinePosition.y);
}
}
}
}
//Vine Thorns
int vineThornCount = this.getCountByType("VineThorn");
if (vineThornCount < 200) {
for (int i = 0; i < 200 - vineThornCount; i++) {
boolean canSpawn = true;
int level = Rand.getRange(1, 3);
Point vinePosition = new Point();
vinePosition.x = Rand.getRange(1, gameController.getMapWidth());
vinePosition.y = Rand.getRange(registry.getBlockManager().getLevelBottom(level),
registry.getBlockManager().getLevelTop(level));
vinePosition.y = this.findNextFloor(vinePosition.x, vinePosition.y, 60);
if (this.doesRectContainBlocks(vinePosition.x, vinePosition.y + 100, 17, 16)) {
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getName().equals("BlueThorn") || monster.getName().equals("VineThorn")) {
double distance = vinePosition.distance(monster.getCenterPoint());
if (distance < 750) {
canSpawn = false;
break;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
if (canSpawn) {
spawn("VineThorn", "Roaming", vinePosition.x, vinePosition.y);
}
}
}
}
}
}
public float getShouldSpawn(MonsterType mt, int groundLevel) {
float[] levelCounts = new float[5];
switch (mt) {
case AggressiveSnake:
levelCounts[0] = 3.50f / 120.0f;
levelCounts[1] = 4.5f / 120.0f;
levelCounts[2] = 3.0f / 120.0f;
levelCounts[3] = 2.0f / 120.0f;
levelCounts[4] = 1.0f / 120.0f;
break;
case LionFly:
levelCounts[0] = 1.50f / 120.0f;
levelCounts[1] = 0.0f;
levelCounts[2] = 0.0f;
levelCounts[3] = 0.0f;
levelCounts[4] = 0.0f;
break;
case Orc:
levelCounts[0] = 0.0f;
levelCounts[1] = 5.5f / 120.0f;
levelCounts[2] = 8.0f / 120.0f;
levelCounts[3] = 6.5f / 120.0f;
levelCounts[4] = 0.0f;
break;
case Pig:
levelCounts[0] = 2.5f / 120.0f;
levelCounts[1] = 0.0f;
levelCounts[2] = 0.0f;
levelCounts[3] = 0.0f;
levelCounts[4] = 0.0f;
break;
case Porcupine:
levelCounts[0] = 3.50f / 120.0f;
levelCounts[1] = 6.5f / 120.0f;
levelCounts[2] = 0.0f;
levelCounts[3] = 0.0f;
levelCounts[4] = 0.0f;
break;
case RedOrc:
levelCounts[0] = 0.0f;
levelCounts[1] = 0.5f / 120.0f;
levelCounts[2] = 4.5f / 120.0f;
levelCounts[3] = 7.5f / 120.0f;
levelCounts[4] = 8.5f / 120.0f;
break;
case RockMonster:
levelCounts[0] = 2.0f / 120.0f;
levelCounts[1] = 1.0f / 120.0f;
levelCounts[2] = 1.0f / 120.0f;
levelCounts[3] = 1.0f / 120.0f;
levelCounts[4] = 1.0f / 120.0f;
break;
case Snail:
levelCounts[0] = 3.0f / 120.0f;
levelCounts[1] = 2.5f / 120.0f;
levelCounts[2] = 1.0f / 120.0f;
levelCounts[3] = 0.0f;
levelCounts[4] = 0.0f;
break;
case Snake:
levelCounts[0] = 3.75f / 120.0f;
levelCounts[1] = 4.5f / 120.0f;
levelCounts[2] = 3.0f / 120.0f;
levelCounts[3] = 2.0f / 120.0f;
levelCounts[4] = 1.0f / 120.0f;
break;
case SpiderWorm:
levelCounts[0] = 0.0f;
levelCounts[1] = 0.0f;
levelCounts[2] = 2.0f / 120.0f;
levelCounts[3] = 6.5f / 120.0f;
levelCounts[4] = 8.0f / 120.0f;
break;
case ZombieWalrus:
levelCounts[0] = 2.25f / 120.0f;
levelCounts[1] = 2.75f / 120.0f;
levelCounts[2] = 0.75f / 120.0f;
levelCounts[3] = 0.0f;
levelCounts[4] = 0.0f;
break;
}
float ret = 0.0f;
if (groundLevel >= 0 && groundLevel < levelCounts.length) {
ret = levelCounts[groundLevel];
} else {
ret = levelCounts[4];
}
return ret;
}
public Monster getSelectedMob() {
if (selectedMob != null) {
if (selectedMob.getIsDead() || selectedMob.isDirty) {
selectedMob = null;
} else {
if (!this.isInPlayerView(selectedMob.getCenterPoint())) {
selectedMob = null;
}
}
}
return selectedMob;
}
public boolean handleClick(Player p, Point clickPoint) {
Point mousePos = new Point(this.panelToMapX(clickPoint.x), this.panelToMapY(clickPoint.y));
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster != null) {
if (monster.isInside(mousePos) && !monster.getIsHiding()) {
if (selectedMob != monster) {
SoundClip cl = new SoundClip("Misc/Click");
selectedMob = monster;
}
return true;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return false;
}
public Monster spawn(String type, String spawnType, int x, int y) {
Monster monster = null;
//for (int i = 0; i < qty; i++) {
if (type.toLowerCase().equals("aggressivesnake")) {
monster = new AggressiveSnake(this, registry, "Monsters/AggressiveSnake/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("bluethorn")) {
monster = new BlueThorn(this, registry, "Monsters/BlueThorn/BlueThorn1", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("bossorc")) {
monster = new BossOrc(this, registry, "Monsters/BossOrc/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("snailrider")) {
monster = new SnailRider(this, registry, "Monsters/SnailRider/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("lionfly")) {
monster = new LionFly(this, registry, "Monsters/LionFly/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("orc")) {
monster = new Orc(this, registry, "Monsters/Orc/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("pig")) {
monster = new Pig(this, registry, "Monsters/Pig/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("porcupine")) {
monster = new Porcupine(this, registry, "Monsters/Porcupine/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("redorc")) {
monster = new RedOrc(this, registry, "Monsters/RedOrc/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("rockmonster")) {
monster = new RockMonster(this, registry, "Monsters/RockMonster/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("snail")) {
monster = new Snail(this, registry, "Monsters/Snail/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("snake")) {
monster = new Snake(this, registry, "Monsters/Snake/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("spiderworm")) {
monster = new SpiderWorm(this, registry, "Monsters/SpiderWorm/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("vinethorn")) {
monster = new VineThorn(this, registry, "Monsters/VineThorn/VineThorn1", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
} else if (type.toLowerCase().equals("zombiewalrus")) {
monster = new ZombieWalrus(this, registry, "Monsters/ZombieWalrus/Standing", spawnType, x, y, mobSpawnRangeMin, mobSpawnRangeMax);
registerMonster(monster);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(monster);
}
}
}
//}
return monster;
}
public void dropLoot(Monster m, int x, int y, ArrayList<Drop> drops) {
gameController.dropLoot(m, x, y, drops);
}
public Damage getMonsterTouchDamage(Rectangle r, int x) {
Damage damage = null;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
damage = monster.getMonsterTouchDamage(r, x);
if (damage != null) {
break;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return damage;
}
public ArrayList<String> attackDamageAndKnockBack(Actor source, Arc2D.Double arc, Point mapPoint, int damage, int knockBackX, int knockBackY, int maxHits, String weaponType) {
int dmg = 0;
int hits = 0;
Monster monster = null;
ArrayList<String> monstersHit = new ArrayList<String>();
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (weaponType != null) {
if (weaponType.equals("Net")) {
damage = 1;
}
}
dmg = monster.attackDamageAndKnockBack(source, arc, mapPoint, damage, knockBackX, knockBackY, weaponType);
if (dmg > 0) {
if (weaponType != null) {
if (weaponType.equals("FangClaw")) {
monster.poison(10);
}
}
monstersHit.add(monster.getName());
hits++;
}
if (hits >= maxHits) {
break;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
if (hits == 0) {
if (source != null) {
SoundClip cl = new SoundClip(registry, "Weapon/Miss", source.getCenterPoint());
} else {
SoundClip cl = new SoundClip("Weapon/Miss");
}
}
return monstersHit;
}
public void showRects(Boolean r) {
showRect = r;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
monster.setShowRect(r);
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public void showGoals(Boolean g) {
showGoals = g;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
monster.setShowGoals(g);
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public boolean getShowGoals() {
return showGoals;
}
@Override
public boolean checkMobProjectileHit(Projectile p) {
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getPerimeter().intersects(p.getRect())) {
monster.applyDamage(p.getDamage(), p.getSource(), p.isFromPlaceable());
return true;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
return false;
}
@Override
public boolean checkMobParticleHit(Particle p) {
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getPerimeter().intersects(p.getRect())) {
monster.applyDamage(p.getDamage(), p.getSource(), p.isFromPlaceable(), false);
return true;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
return false;
}
@Override
public void update() {
if (!transmitting) {
super.update();
ArrayList deadMonsters = new ArrayList();
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster != null) {
monster.update();
if (monster.getIsDead()) {
deadMonsters.add(key);
}
}
}
if (deadMonsters.size() > 0) {
for (int i = 0; i < deadMonsters.size(); i++) {
//EIError.debugMsg((String) deadMonsters.get(i));
monsters.remove((String) deadMonsters.get(i));
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
}
private void removeMonster(String monsterType) {
Monster monster = null;
ArrayList deadMonsters = new ArrayList();
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getName().equals(monsterType)) {
deadMonsters.add(key);
break;
}
}
if (deadMonsters.size() > 0) {
for (int i = 0; i < deadMonsters.size(); i++) {
//EIError.debugMsg((String) deadMonsters.get(i));
monsters.remove((String) deadMonsters.get(i));
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
private int getSpawnCount(String monsterType) {
int count = 0;
Monster monster = null;
ArrayList deadMonsters = new ArrayList();
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getName().equals(monsterType)) {
count++;
break;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return count;
}
public void removeAllMonsters(Rectangle area) {
Monster monster = null;
ArrayList deadMonsters = new ArrayList();
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster != null) {
if (!monster.getName().equals("Pig") && !monster.getName().equals("BlueThorn") && !monster.getName().equals("VineThorn") && monster.getPerimeter().intersects(area)) {
deadMonsters.add(key);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateMonster um = new UpdateMonster(monster.getId());
um.mapX = monster.getMapX();
um.mapY = monster.getMapY();
um.action = "Die";
registry.getNetworkThread().sendData(um);
}
}
}
}
}
if (deadMonsters.size() > 0) {
for (int i = 0; i < deadMonsters.size(); i++) {
monsters.remove((String) deadMonsters.get(i));
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public void removeAllMonsters() {
Monster monster = null;
ArrayList deadMonsters = new ArrayList();
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (!monster.getName().equals("Pig") && !monster.getName().equals("BlueThorn") && !monster.getName().equals("VineThorn")) {
deadMonsters.add(key);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateMonster um = new UpdateMonster(monster.getId());
um.mapX = monster.getMapX();
um.mapY = monster.getMapY();
um.action = "Die";
registry.getNetworkThread().sendData(um);
}
}
}
}
if (deadMonsters.size() > 0) {
for (int i = 0; i < deadMonsters.size(); i++) {
monsters.remove((String) deadMonsters.get(i));
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public int getCountByTypeWithinXRange(String type, int xStart, int xEnd) {
int count = 0;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getName().equals(type) && monster.getMapX() >= xStart && monster.getMapX() <= xEnd) {
count++;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return count;
}
private int getCountByType(String type) {
int count = 0;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getName().equals(type)) {
count++;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return count;
}
public int getAnimalCount(Rectangle r) {
int count = 0;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getName().equals("Pig")) {
if (monster.getSpriteRect().intersects(r)) {
count++;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return count;
}
public boolean spawnBossOrc(Player player) {
if (getSpawnCount("BossOrc") < 1) {
registry.showMessage("Success", "Beware, Melvin lurks nearby...");
spawn("BossOrc", "Roaming", player.getMapX(), player.getMapY());
return true;
}
return false;
}
public boolean spawnSnailRider(Player player) {
if (getSpawnCount("SnailRider") < 1) {
registry.showMessage("Success", "Suddenly, a wild Snail Rider appears!");
spawn("SnailRider", "Roaming", player.getMapX(), player.getMapY());
return true;
}
return false;
}
public void spawnNearPlayers() {
Monster monster = null;
float prob, rand;
int count;
HashMap<String, Player> players = registry.getPlayerManager().getPlayers();
Player player = null;
Integer spawnCoolDown = null;
for (String key : players.keySet()) {
player = (Player) players.get(key);
//check for spawning Melvin
if (registry.currentTime >= nextBossOrcSpawn && nextBossOrcSpawn != 0) {
//to spawn melvin, player must have 40 AP, be within a range on the map and be on the surface
if (player.getMapX() >= 2000 && player.getMapX() <= 5000 && player.getLevel() >= 10 && player.getMapY() == this.findFloor(player.getMapX())) {
spawnBossOrc(player);
}
}
if (spawnCoolDowns.containsKey(key)) {
spawnCoolDown = spawnCoolDowns.get(key);
} else {
spawnCoolDown = new Integer(0);
spawnCoolDowns.put(key, spawnCoolDown);
}
spawnCoolDown--;
if (spawnCoolDown < 0) {
int x = player.getMapX();
int y = player.getMapY();
int groundLevel = registry.getBlockManager().getLevelByY(y);
count = -groundLevel;
try {
for (String key2 : monsters.keySet()) {
monster = (Monster) monsters.get(key2);
if (monster.getCenterPoint().distance(player.getCenterPoint()) < MonsterManager.mobSpawnRangeMax * 3 / 2) {
if (monster.getTouchDamage() > 0 && !monster.getName().equals("BlueThorn") && !monster.getName().equals("VineThorn")) {
count++;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
if (count < 4) {
for (MonsterType monsterType : MonsterType.values()) {
if (count < 4) {
rand = Rand.getFloat();
prob = getShouldSpawn(monsterType, groundLevel);
if (prob > 0.0f) {
if ((prob - count * spawnRatioDiff) > 0.005f) {
prob += -count * spawnRatioDiff;
} else {
prob = 0.005f;
}
}
if (rand <= prob) {
//System.out.println("spawn near player " + monsterType.name());
spawn(monsterType.name(), "Roaming", x, y);
count++;
}
}
}
} else {
//EIError.debugMsg("too many to spawn");
spawnCoolDown = 20;
}
}
}
}
public void spawnNearPlaceable() {
float prob, rand;
Placeable placeable = registry.getPlaceableManager().getRandomPlacable();
if (placeable != null && !placeable.getType().equals("TownHall") && !placeable.getType().equals("Cabin") && !placeable.getType().equals("Chest")) {
Point p = placeable.getCenterPoint();
HashMap<String, Player> players = registry.getPlayerManager().getPlayers();
Player player = null;
boolean playerNear = false;
for (String key : players.keySet()) {
player = (Player) players.get(key);
Point p2 = new Point(player.getMapX(), player.getMapY());
if (p.distance(p2) < mobSpawnRangeMin * 2) {
playerNear = true;
}
}
if (!playerNear) {
for (MonsterType monsterType : MonsterType.values()) {
if (monsterType.toString().equals("Porcupine") || monsterType.toString().equals("Snail") || monsterType.toString().equals("Snake") || monsterType.toString().equals("ZombieWalrus")) {
rand = Rand.getFloat();
prob = getShouldSpawn(monsterType, 0);
if (rand <= prob / 3.0f) {
//System.out.println("spawn near placeable " + monsterType.name());
spawn(monsterType.name(), "Roaming", p.x, p.y);
}
}
}
}
}
}
public void setNextBossOrcSpawn(int s) {
nextBossOrcSpawn = s;
}
public void setNextSnailRiderSpawn(int s) {
nextSnailRiderSpawn = s;
}
@Override
public void updateLong() {
if (!transmitting) {
if (nextBossOrcSpawn == 0) {
//spawn melvin every 10 - 30 min
nextBossOrcSpawn = registry.currentTime + Rand.getRange(10 * 60 * 1000, 30 * 60 * 1000);
}
if (nextSnailRiderSpawn == 0) {
//spawn melvin every 10 - 30 min
nextSnailRiderSpawn = registry.currentTime + Rand.getRange(10 * 60 * 1000, 30 * 60 * 1000);
}
Monster monster = null;
ArrayList deadMonsters = new ArrayList();
//make sure we have enough bad guys on the map
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
spawnNearPlayers();
spawnNearPlaceable();
}
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (!monster.isFeared()) {
gameController.checkIfFeared(monster);
}
gameController.checkPlaceableDamageAgainstMob(monster);
monster.updateLong();
if (monster.isDirty()) {
deadMonsters.add(key);
}
}
if (deadMonsters.size() > 0) {
for (int i = 0; i < deadMonsters.size(); i++) {
//EIError.debugMsg((String) deadMonsters.get(i));
monsters.remove((String) deadMonsters.get(i));
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
}
public void render(Graphics g) {
if (!transmitting) {
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
monster.render(g);
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
}
private int getRoamingCount() {
int count = 0;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (monster.getSpawnType().equals("Roaming")) {
count++;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return count;
}
public void resetAggro() {
int count = 0;
Monster monster = null;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
monster.setPlayerDamage(0);
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public HashMap<String, Monster> getMonsters() {
return monsters;
}
public Monster getClosestInPanel(Point p) {
Monster monster = null;
Monster closestMonster = null;
double closestDistance = 0;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (!monster.getName().equals("Pig") && !monster.getName().equals("BlueThorn") && !monster.getName().equals("VineThorn")) {
if (monster.getIsInPanel()) {
double distance = p.distance(monster.getCenterPoint());
if (distance < closestDistance || closestDistance == 0) {
closestMonster = monster;
closestDistance = distance;
}
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return closestMonster;
}
public Monster getClosestWithinMax(Point p, int r) {
Monster monster = null;
Monster closestMonster = null;
double closestDistance = 0;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (!monster.getName().equals("Pig") && !monster.getName().equals("BlueThorn") && !monster.getName().equals("VineThorn")) {
if (monster.getIsInPanel()) {
double distance = p.distance(monster.getCenterPoint());
if ((distance < closestDistance || closestDistance == 0) && distance <= r) {
closestMonster = monster;
closestDistance = distance;
}
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return closestMonster;
}
public Monster getMostAggroInPanel(Point p) {
Monster monster = null;
Monster mostAggroMonster = null;
double mostAggro = 0;
try {
for (String key : monsters.keySet()) {
monster = (Monster) monsters.get(key);
if (!monster.getName().equals("Pig") && !monster.getName().equals("BlueThorn") && !monster.getName().equals("VineThorn")) {
if (monster.getIsInPanel()) {
double distance = p.distance(monster.getCenterPoint());
if (monster.getPlayerDamage() > mostAggro) {
mostAggroMonster = monster;
mostAggro = monster.getPlayerDamage();
}
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify monsters while iterating
//we'll continue and the new item can be grabbed on the next update
}
return mostAggroMonster;
}
public void processMonsterUpdateUDP(UDPMonster up) {
if (up != null) {
if (monsters.containsKey(up.id)) {
Monster monster = monsters.get(up.id);
if (monster != null) {
monster.processUpdate(up);
}
}
}
}
public void processMonsterUpdate(UpdateMonster um) {
if (um != null) {
if (monsters.containsKey(um.id)) {
Monster monster = monsters.get(um.id);
if (monster != null) {
EIError.debugMsg("Setting " + um.id + " to " + um.mapX + ":" + um.mapY + ", Action: " + um.action);
monster.setPosition(um.mapX, um.mapY);
if (um.previousGoal != null) {
monster.ai.setPreviousGoal(um.previousGoal);
}
if (um.currentGoal != null) {
monster.ai.setCurrentGoal(um.currentGoal);
}
if (um.action.equals("ApplyDamage")) {
monster.applyDamage(um.dataInt, um.actor);
} else if (um.action.equals("ApplyKnockBack")) {
monster.applyKnockBack(um.dataInt, um.dataInt2);
} else if (um.action.equals("Die")) {
monster.setHitPoints(0);
} else if (um.action.equals("Fear")) {
monster.applyKnockBack(um.dataInt, um.dataInt2);
monster.fear(um.dataPoint, um.dataLong);
}
}
} else {
if (gameController.multiplayerMode == gameController.multiplayerMode.CLIENT && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
EIError.debugMsg("Monster not found - need " + um.id);
registry.getNetworkThread().sendData("send monster data: " + um.id);
}
}
}
}
}
private void readObject(ObjectInputStream aInputStream) throws Exception {
aInputStream.defaultReadObject();
}
private void writeObject(ObjectOutputStream aOutputStream) throws Exception {
transmitting = true;
aOutputStream.defaultWriteObject();
transmitting = false;
}
@Override
public Object clone() {
Object ret = null;
try {
ret = super.clone();
} catch (CloneNotSupportedException e) {
}
return ret;
}
}