package com.weem.epicinventor.placeable;
import com.weem.epicinventor.*;
import com.weem.epicinventor.actor.*;
import com.weem.epicinventor.actor.monster.*;
import com.weem.epicinventor.drop.*;
import com.weem.epicinventor.hud.*;
import com.weem.epicinventor.inventory.*;
import com.weem.epicinventor.network.*;
import com.weem.epicinventor.projectile.*;
import com.weem.epicinventor.utility.*;
import com.weem.epicinventor.world.block.*;
import java.awt.*;
import java.util.*;
import java.io.*;
import java.util.ArrayList;
enum PlaceableType {
AutoXBow,
BladeTrap,
BookShelf,
Box,
Cabin,
Chest,
CopperMine,
Crate,
EmeraldTeleporter,
Forge,
GoldMine,
LargeFarm,
LargeSafe,
LionFlyStatue,
IronMine,
ItemContainer,
MedicKit,
MediumSafe,
Pasture,
PlatinumMine,
PottedFlower,
RubyTeleporter,
SapphireTeleporter,
SawMill,
ScareCrow,
SilverMine,
SmallFarm,
SmallSafe,
SteamEngine,
StoneMine,
ThornTrap,
TownBlock,
TownHall,
WindMill,
WeaponRack,
WorkBench
}
public class PlaceableManager extends Manager implements Serializable, Cloneable {
protected static final long serialVersionUID = 10000L;
private HashMap<String, Placeable> placeables;
Placeable currentlyPlacing;
private final static int MAX_POWER_DISTANCE = 550; //in pixels
public PlaceableManager() {
super();
}
public PlaceableManager(GameController gc, Registry rg) {
super(gc, rg);
placeables = new HashMap<String, Placeable>();
generateChests();
}
private void generateChests() {
int chestWidth = 34;
int chestHeight = 23;
int[] chestLevels = {2, 2, 3, 3, 4, 5};
for (int level = 0; level < chestLevels.length; level++) {
for (int count = 0; count < chestLevels[level]; count++) {
boolean chestPlaced = false;
do {
Point p = this.getNewXY(gameController.getMapWidth(), chestHeight, level);
int y = findNextFloor(p.x + chestWidth, p.y, chestHeight);
if (p.y == y) {
//make sure the chest isn't spawned in view
Placeable chest = loadChest(p.x, p.y - 16);
chestPlaced = true;
}
} while (!chestPlaced);
}
}
}
public Point getNewXY(int mapWidth, int height, int level) {
Point p = new Point(0, 0);
p.x = Rand.getRange(1, mapWidth);
Registry r = registry;
BlockManager bm = r.getBlockManager();
p.y = Rand.getRange(bm.getLevelBottom(level),
bm.getLevelTop(level));
p.y = this.findNextFloor(p.x - 1, p.y, height);
return p;
}
@Override
public void setTransient(Registry rg) {
super.setTransient(rg);
try {
for (String key : placeables.keySet()) {
Placeable placeable = (Placeable) placeables.get(key);
//convert town halls to cabins
if (placeable.getType().equals("TownHall")) {
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
placeable.setIsDirty(true);
Placeable cabin = new Cabin(this, registry, "Placeables/Cursor/Cabin", "Placeables/Placed/Cabin", placeable.getMapX(), placeable.getMapY(), Placeable.State.Placed);
registerPlaceable(cabin);
}
} else {
placeable.setTransient(rg);
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public Placeable getRandomPlacable() {
Placeable p = null;
Object[] ks = placeables.keySet().toArray();
if (ks.length > 0) {
String s = ks[Rand.getRange(0, ks.length - 1)].toString();
p = placeables.get(s);
}
return p;
}
public boolean isPlaceableWithin(Point p, int dist) {
boolean ret = false;
for (String key : placeables.keySet()) {
Placeable placeable = placeables.get(key);
if (placeable.getCenterPoint().distance(p) <= dist) {
ret = true;
}
}
return ret;
}
public void registerPlaceable(Placeable p) {
if (!placeables.containsKey(p.getId())) {
placeables.put(p.getId(), p);
}
}
public HashMap<String, Placeable> getPlaceables() {
return placeables;
}
public Placeable getPlaceableById(String id) {
if (placeables.containsKey(id)) {
Placeable placeable = placeables.get(id);
return placeable;
} else {
return null;
}
}
public Placeable loadPlaceable(String n, int x, int y) {
return loadPlaceable(n, x, y, Placeable.State.New);
}
public Placeable loadPlaceable(String n, int x, int y, Placeable.State state) {
Placeable placeable = null;
Player p = registry.getPlayerManager().getCurrentPlayer();
int mapY = findNextFloor(x, y, 1);
if (state == Placeable.State.Placed) {
mapY = y;
}
PlaceableType whichPlaceable = PlaceableType.valueOf(n);
switch (whichPlaceable) {
case AutoXBow:
placeable = new AutoXBow(this, registry, "Placeables/Cursor/AutoXBow", "", x, mapY, state);
break;
case BladeTrap:
placeable = new BladeTrap(this, registry, "Placeables/Cursor/BladeTrap", "Placeables/Placed/BladeTrap", x, mapY, state);
break;
case BookShelf:
placeable = new BookShelf(this, registry, "Placeables/Cursor/BookShelf", "Placeables/Placed/BookShelf", x, mapY, state);
break;
case Box:
placeable = new Box(this, registry, "Placeables/Cursor/Box", "Placeables/Placed/Box", x, mapY, state);
break;
case Cabin:
placeable = new Cabin(this, registry, "Placeables/Cursor/Cabin", "Placeables/Placed/Cabin", x, mapY, state);
break;
case Chest:
placeable = new Chest(this, registry, "Placeables/Cursor/Chest", "Placeables/Placed/Chest", x, mapY, state);
break;
case CopperMine:
placeable = new CopperMine(this, registry, "Placeables/Cursor/CopperMine", "Placeables/Placed/CopperMine", x, mapY, state);
break;
case Crate:
placeable = new Crate(this, registry, "Placeables/Cursor/Crate", "Placeables/Placed/Crate", x, mapY, state);
break;
case EmeraldTeleporter:
placeable = new EmeraldTeleporter(this, registry, "Placeables/Cursor/EmeraldTeleporter", "Placeables/Placed/EmeraldTeleporter", x, mapY, state);
break;
case Forge:
placeable = new Forge(this, registry, "Placeables/Cursor/Forge", "Placeables/Placed/Forge", x, mapY, state);
break;
case GoldMine:
placeable = new GoldMine(this, registry, "Placeables/Cursor/GoldMine", "Placeables/Placed/GoldMine", x, mapY, state);
break;
case IronMine:
placeable = new IronMine(this, registry, "Placeables/Cursor/IronMine", "Placeables/Placed/IronMine", x, mapY, state);
break;
case LargeFarm:
placeable = new LargeFarm(this, registry, "Placeables/Cursor/LargeFarm", "", x, mapY, state);
break;
case LargeSafe:
placeable = new LargeSafe(this, registry, "Placeables/Cursor/LargeSafe", "", x, mapY, state);
break;
case LionFlyStatue:
placeable = new LionFlyStatue(this, registry, "Placeables/Cursor/LionFlyStatue", "Placeables/Placed/LionFlyStatue", x, mapY, state);
break;
case MedicKit:
placeable = new MedicKit(this, registry, "Placeables/Cursor/MedicKit", "", x, mapY, state);
break;
case MediumSafe:
placeable = new MediumSafe(this, registry, "Placeables/Cursor/MediumSafe", "", x, mapY, state);
break;
case Pasture:
placeable = new Pasture(this, registry, "Placeables/Cursor/Pasture", "", x, mapY, state);
break;
case PlatinumMine:
placeable = new PlatinumMine(this, registry, "Placeables/Cursor/PlatinumMine", "Placeables/Placed/PlatinumMine", x, mapY, state);
break;
case PottedFlower:
placeable = new PottedFlower(this, registry, "Placeables/Cursor/PottedFlower", "Placeables/Placed/PottedFlower", x, mapY, state);
break;
case RubyTeleporter:
placeable = new RubyTeleporter(this, registry, "Placeables/Cursor/RubyTeleporter", "Placeables/Placed/RubyTeleporter", x, mapY, state);
break;
case SapphireTeleporter:
placeable = new SapphireTeleporter(this, registry, "Placeables/Cursor/SapphireTeleporter", "Placeables/Placed/SapphireTeleporter", x, mapY, state);
break;
case SawMill:
placeable = new SawMill(this, registry, "Placeables/Cursor/SawMill", "Placeables/Placed/SawMill", x, mapY, state);
break;
case ScareCrow:
placeable = new ScareCrow(this, registry, "Placeables/Cursor/ScareCrow", "", x, mapY, state);
break;
case SilverMine:
placeable = new SilverMine(this, registry, "Placeables/Cursor/SilverMine", "Placeables/Placed/SilverMine", x, mapY, state);
break;
case SmallFarm:
placeable = new SmallFarm(this, registry, "Placeables/Cursor/SmallFarm", "", x, mapY, state);
break;
case SmallSafe:
placeable = new SmallSafe(this, registry, "Placeables/Cursor/SmallSafe", "", x, mapY, state);
break;
case SteamEngine:
placeable = new SteamEngine(this, registry, "Placeables/Cursor/SteamEngine", "Placeables/Placed/SteamEngine", x, mapY, state);
break;
case StoneMine:
placeable = new StoneMine(this, registry, "Placeables/Cursor/StoneMine", "Placeables/Placed/StoneMine", x, mapY, state);
break;
case ThornTrap:
placeable = new ThornTrap(this, registry, "Placeables/Cursor/ThornTrap", "", x, mapY, state);
break;
case TownBlock:
placeable = new TownBlock(this, registry, "Placeables/Cursor/TownBlock", "Placeables/Placed/TownBlock", x, mapY, state);
break;
case TownHall:
placeable = new Building(this, registry, "Placeables/Cursor/TownHall", "Placeables/Placed/TownHall", x, mapY, state);
break;
case WeaponRack:
placeable = new WeaponRack(this, registry, "Placeables/Cursor/WeaponRack", "Placeables/Placed/WeaponRack", x, mapY, state);
break;
case WindMill:
placeable = new WindMill(this, registry, "Placeables/Cursor/WindMill", "Placeables/Placed/WindMill", x, mapY, state);
break;
case WorkBench:
placeable = new WorkBench(this, registry, "Placeables/Cursor/WorkBench", "Placeables/Placed/WorkBench", x, mapY, state);
break;
}
int[] range = gameController.getTownStartEnd(x, y);
if ((placeable.getWidth() > range[1] - range[0] || range[0] == -1 || range[1] == -1) && whichPlaceable != PlaceableType.TownBlock) {
registry.showMessage("Error", "Not enough town blocks to place that");
} else {
if (state == Placeable.State.Placed) {
if (isOverOther(placeable)) {
placeable = null;
}
if (placeable != null) {
registerPlaceable(placeable);
if (state == Placeable.State.Placed) {
if (isOverOther(placeable)) {
placeable = null;
}
placeable.setIsBuilding(true);
if (registry.getGameController().multiplayerMode == registry.getGameController().multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(placeable);
}
}
}
}
} else {
if (placeable != null) {
registerPlaceable(placeable);
currentlyPlacing = placeable;
}
}
}
return placeable;
}
public Placeable loadInitialTownHall(int x) {
int mapY = 0;
Placeable placeable = null;
mapY = findFloor(x);
placeable = new Cabin(this, registry, "Placeables/Placed/Cabin", "Placeables/Placed/Cabin", x, mapY, Placeable.State.Placed);
registerPlaceable(placeable);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(placeable);
}
}
return placeable;
}
public Placeable loadContainer(int x, ArrayList<Drop> drops) {
int mapY = 0;
Placeable placeable = null;
mapY = findFloor(x);
placeable = new ItemContainer(this, registry, "Placeables/Placed/ItemContainer", "Placeables/Placed/ItemContainer", x, mapY, Placeable.State.Placed, drops);
registerPlaceable(placeable);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(placeable);
}
}
return placeable;
}
public Placeable loadChest(int x, int y) {
Placeable placeable = new Chest(this, registry, "Placeables/Placed/Chest", "Placeables/Placed/Chest", x, y, Placeable.State.Placed);
registerPlaceable(placeable);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(placeable);
}
}
return placeable;
}
public int getHPRegenerationBonus(Point p) {
int bonus = 0;
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
bonus += placeable.getHPRegenerationBonus(p);
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return bonus;
}
@Override
public boolean checkPlaceableProjectileHit(Projectile p) {
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
if (placeable.getPerimeter().contains(p.getCenterPoint())) {
placeable.applyDamage((Monster) p.getSource(), p.getDamage());
return true;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
return false;
}
public float getAttackBonus(Point p) {
float bonus = 0;
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
bonus += placeable.getAttackBonus(p);
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return bonus;
}
@Override
public int getActivatedCount(String type) {
int count = 0;
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
if (placeable.isActivated() && placeable.getItemName().equals(type)) {
count++;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return count;
}
public int getTotalCount(String type, Placeable skipPlaceable) {
int count = 0;
HashMap<String, Placeable> tempHashMap = new HashMap<String, Placeable>(placeables);
Placeable placeable = null;
try {
for (String key : tempHashMap.keySet()) {
placeable = (Placeable) tempHashMap.get(key);
if (placeable != null) {
String testString = placeable.getItemName();
if (type.equals(testString) && placeable != skipPlaceable) {
count++;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return count;
}
public boolean handleClick(Player p, Point clickPoint) {
if (p == registry.getPlayerManager().getCurrentPlayer()) {
return placeCurrent(p);
} else {
return false;
}
}
public boolean handleRightClick(Point clickPoint) {
Placeable placeable = null;
//start from the top and work our way down to "layer" the huds
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable.handleRightClick(clickPoint)) {
return true;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return false;
}
public void toggleContainerHUD(HUD h) {
gameController.toggleContainerHUD(h);
}
public void stopDestroy(Player p) {
if (p == registry.getPlayerManager().getCurrentPlayer()) {
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
placeable.setDestroying(null, false);
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
}
public boolean startDestroy(Player player) {
Placeable placeable = null;
Placeable closestPlaceable = null;
Point p = null;
double closestDistance = 0;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
placeable.setDestroying(null, false);
p = new Point(placeable.getCenterPoint());
p.y -= (placeable.getHeight() / 2);
if (player.getCenterPoint().distance(p) < closestDistance || closestDistance == 0) {
closestPlaceable = placeable;
closestDistance = player.getCenterPoint().distance(p);
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify resources while iterating
//we'll continue and the new item can be grabbed on the next update
}
if (closestPlaceable != null) {
if (closestDistance <= closestPlaceable.width / 2 || closestDistance <= 16) {
if (closestPlaceable.canDestroy()
&& !closestPlaceable.getType().equals("TownHall")
&& !closestPlaceable.getType().equals("ItemContainer")) {
if (closestPlaceable.setDestroying(player, true)) {
return true;
}
}
}
}
return false;
}
public void placeableDoneDestroying(Placeable p) {
Player player = p.getDestroyingPlayer();
gameController.stopGather(player);
if (player != null) {
if (gameController.playerAddItem(player, p.getItemName(), 1) == 0) {
p.destroy();
SoundClip cl = new SoundClip("Player/Good");
}
}
if (gameController.multiplayerMode != gameController.multiplayerMode.NONE && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdatePlaceable up = new UpdatePlaceable(p.getId());
up.action = "DoneDestroying";
registry.getNetworkThread().sendData(up);
}
}
}
public boolean teleportPlayer(Placeable p) {
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable.getType().equals(p.getType()) && placeable != p) {
Player player = registry.getPlayerManager().getCurrentPlayer();
if (player != null) {
SoundClip cl = new SoundClip("Misc/Teleport");
player.setPosition(placeable.getCenterPoint().x - 25, placeable.getMapY());
return true;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
registry.showMessage("Error", "No matching teleporter found");
return false;
}
public boolean placeCurrent(Player p) {
int slot = p.getSelectedItemIndex();
String itemName = playerGetInventoryItemName(slot);
if(currentlyPlacing != null && !currentlyPlacing.getItemName().equals(itemName)) {
p.handleRightClick();
registry.showMessage("Error", "You must stay selected on a placeable on your quick-bar in order to place it.");
currentlyPlacing = null;
}
if (currentlyPlacing != null && currentlyPlacing.checkCanPlace()) {
String currentlyPlacingType = currentlyPlacing.getType();
if (currentlyPlacingType.equals("EmeraldTeleporter")) {
if (this.getTotalCount("EmeraldTeleporter", currentlyPlacing) >= 2) {
registry.showMessage("Error", "You can only place 2 Emerald Teleporters at a time");
return false;
}
}
if (currentlyPlacingType.equals("RubyTeleporter")) {
if (this.getTotalCount("RubyTeleporter", currentlyPlacing) >= 2) {
registry.showMessage("Error", "You can only place 2 Ruby Teleporters at a time");
return false;
}
}
if (currentlyPlacingType.equals("SapphireTeleporter")) {
if (this.getTotalCount("SapphireTeleporter", currentlyPlacing) >= 2) {
registry.showMessage("Error", "You can only place 2 Sapphire Teleporters at a time");
return false;
}
}
currentlyPlacing.setState(Placeable.State.Placed);
if (registry.getGameController().multiplayerMode == registry.getGameController().multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(currentlyPlacing);
}
} else if (gameController.multiplayerMode == gameController.multiplayerMode.CLIENT && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData("place " + currentlyPlacing.getType() + " " + currentlyPlacing.getMapX() + " " + currentlyPlacing.getMapY());
}
currentlyPlacing.isDirty = true;
}
currentlyPlacing = null;
return true;
}
return false;
}
public void cancelPlaceable(Player p) {
if (p == registry.getPlayerManager().getCurrentPlayer()) {
if (currentlyPlacing()) {
if (placeables.containsKey(currentlyPlacing.getId())) {
placeables.remove(currentlyPlacing.getId());
}
currentlyPlacing = null;
}
}
}
public void playerDeleteInventory(int slot, int qty) {
gameController.playerDeleteInventory(slot, qty);
}
public boolean currentlyPlacing() {
if (currentlyPlacing == null) {
return false;
}
return true;
}
@Override
public void monsterAttackPlaceable(Monster source, Rectangle attackRect, int meleeDamage) {
int dmg = 0;
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
dmg = placeable.attackDamage(source, attackRect, meleeDamage);
if (dmg > 0) {
break;
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public int[] getPower() {
int[] powerArray = new int[3];
int usedPower = 0, totalPower = 0, availablePower = 0;
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable.canDestroy()) {
usedPower += placeable.getPowerRequired();
totalPower += placeable.getPowerGenerated();
availablePower += placeable.getPowerGenerated();
availablePower -= placeable.getPowerRequired();
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
powerArray[0] = usedPower;
powerArray[1] = totalPower;
powerArray[2] = availablePower;
return powerArray;
}
public int[] getTownStartEndUnderPlayer() {
return gameController.getTownStartEndUnderPlayer();
}
public Placeable getClosestActivated(Point p) {
Placeable placeable = null;
Placeable closestPlaceable = null;
double closestDistance = 0;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable.isActivated() && !placeable.getItemName().equals("ItemContainer")) {
double distance = p.distance(placeable.getCenterPoint());
if ((distance < closestDistance || closestDistance == 0)
&& !placeable.getType().equals("ItemContiner")
&& !placeable.getType().equals("PlayerContiner")
&& !placeable.getType().equals("Chest")
&& !placeable.getType().equals("TownHall")
&& !placeable.getType().equals("Cabin")) {
closestPlaceable = placeable;
closestDistance = distance;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return closestPlaceable;
}
public Placeable getClosest(Point p) {
Placeable placeable = null;
Placeable closestPlaceable = null;
double closestDistance = 0;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (!placeable.getItemName().equals("ItemContainer")) {
double distance = p.distance(placeable.getCenterPoint());
if ((distance < closestDistance || closestDistance == 0)) {
closestPlaceable = placeable;
closestDistance = distance;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return closestPlaceable;
}
@Override
public Point getNearestTownHallXY(Point p) {
int closestX = 0;
Point townHall = new Point(0, 0);
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable.getType().equals("TownHall") || placeable.getType().equals("Cabin")) {
int distance = (int) placeable.getCenterPoint().distance(p);
if (distance < closestX || closestX == 0) {
closestX = distance;
townHall.x = placeable.getMapX() + (placeable.getWidth() / 2);
townHall.y = placeable.getMapY();
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return townHall;
}
public boolean isOverOther() {
return isOverOther(currentlyPlacing);
}
public boolean isOverOther(Placeable p) {
boolean ret = false;
if (p != null) {
Placeable cp = null;
try {
for (String key : placeables.keySet()) {
cp = (Placeable) placeables.get(key);
if (!cp.getId().equals(p.getId())) {
if ((p.getMapX() >= cp.getMapX() && p.getMapX() < cp.getMapX() + cp.getWidth())
|| (p.getMapX() + p.getWidth() > cp.getMapX() && p.getMapX() + p.getWidth() < cp.getMapX() + cp.getWidth())
|| (p.getMapX() < cp.getMapX() && p.getMapX() + p.getWidth() > cp.getMapX())) {
if (p.getMapY() >= cp.getMapY() && p.getMapY() < cp.getMapY() + cp.getHeight()) {
ret = true;
}
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
return ret;
}
public void checkIfFeared(Monster m) {
int fearValue;
Placeable placeable = null;
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
fearValue = placeable.getFearGenerated();
if (fearValue > 0 && placeable.canDestroy()) {
if (placeable.getCenterPoint().distance(m.getCenterPoint()) <= placeable.getFearDistance()) {
if (Rand.getRange(1, fearValue) == 1) {
m.fear(placeable.getCenterPoint(), placeable.getFearDuration());
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateMonster um = new UpdateMonster(m.getId());
um.mapX = m.getMapX();
um.mapY = m.getMapY();
um.action = "Fear";
um.dataPoint = placeable.getCenterPoint();
um.dataLong = placeable.getFearDuration();
registry.getNetworkThread().sendData(um);
}
}
}
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
}
public void checkPlaceableDamageAgainstMob(Monster m) {
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable.canDestroy()) {
if (placeable.getPerimeter().intersects(m.getPerimeter()) && placeable.isActivated()) {
m.applyDamage(placeable.getTouchDamage(), registry.getPlayerManager().getCurrentPlayer(), true);
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
}
@Override
public void update() {
super.update();
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
placeable.update();
if (placeable.isDirty()) {
placeables.remove(key);
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
if (currentlyPlacing != null) {
Point p = null;
if (currentlyPlacing.getItemName().equals("TownBlock")) {
p = getBlockSnap();
} else {
p = getTownSnap();
}
if (currentlyPlacing.getState() == Placeable.State.New) {
currentlyPlacing.setState(Placeable.State.NotPlaced);
}
currentlyPlacing.setPosition(p.x, p.y);
}
}
protected Point getBlockSnap() {
if (currentlyPlacing != null) {
int x = (gameController.getCurrentMousePosition().x
+ gameController.getMapOffsetX())
/ BlockManager.getBlockWidth()
* BlockManager.getBlockWidth();
int y = (gameController.getMapOffsetY()
- gameController.getCurrentMousePosition().y
+ gameController.getPHeight())
/ BlockManager.getBlockHeight()
* BlockManager.getBlockHeight();
if (!doesRectContainBlocks(x + 1, y + 1, currentlyPlacing.getWidth() - 2, currentlyPlacing.getHeight() - 2)) {
y = findNextFloor(x, y, currentlyPlacing.getHeight()) - BlockManager.getBlockHeight() - currentlyPlacing.getHeight();
}
Point p = new Point(x, y);
return p;
} else {
return new Point(0, 0);
}
}
protected Point getTownSnap() {
Placeable placeable = currentlyPlacing;
if (placeable != null) {
int x = (gameController.getCurrentMousePosition().x
+ gameController.getMapOffsetX())
/ BlockManager.getBlockWidth()
* BlockManager.getBlockWidth();
int[] xStartEnd = getTownStartEndUnderPlayer();
if (xStartEnd[0] != -1) {
if (x < xStartEnd[0]) {
x = xStartEnd[0];
} else if (x + placeable.getWidth() > xStartEnd[1]) {
x = xStartEnd[1] - placeable.getWidth();
}
}
int y = findNextFloor(x, placeable.getMapY(), 1) - BlockManager.getBlockHeight();
if (y <= 0) {
y = placeable.getMapY();
}
Point p = new Point(x, y);
return p;
} else {
return new Point(0, 0);
}
}
@Override
public boolean isInFrontOfPlaceable(Rectangle r) {
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
if (placeable.getPerimeter().intersects(r)) {
return true;
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return false;
}
public Placeable getPasture(Rectangle r) {
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
if (placeable.getType().equals("Pasture")) {
if (placeable.getPerimeter().intersects(r)) {
return placeable;
}
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
return null;
}
@Override
public void updateLong() {
boolean nearArea;
Point placeablePoint, areaPoint;
Placeable placeable = null;
int[] powerValues = this.getPower();
//loop through the placeable to figure out power for each one
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
//only affect placeables which are built and require power
if (placeable.canDestroy() && placeable.getPowerRequired() > 0) {
//check availablePower
if (powerValues[2] < 0) {
placeable.setIsPowered(false);
} else {
placeable.setIsPowered(true);
}
}
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
//run long update for placeables
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
if (placeable != null) {
placeable.updateLong();
}
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public void render(Graphics g) {
Placeable placeable = null;
try {
for (String key : placeables.keySet()) {
placeable = (Placeable) placeables.get(key);
placeable.render(g);
}
} catch (ConcurrentModificationException concEx) {
//another thread was trying to modify placeables while iterating
//we'll continue and the new item can be grabbed on the next update
}
}
public void processPlaceableUpdateUDP(UDPPlaceable up) {
if (up != null) {
if (placeables.containsKey(up.id)) {
Placeable placeable = placeables.get(up.id);
if (placeable != null) {
placeable.processUpdate(up);
}
}
}
}
public void processPlaceableUpdate(UpdatePlaceable up) {
EIError.debugMsg("Setting Placeable " + up.id + ", Action: " + up.action);
if (up != null) {
if (placeables.containsKey(up.id)) {
Placeable placeable = placeables.get(up.id);
if (placeable != null) {
if (up.mapY > 0) {
placeable.setPosition(up.mapX, up.mapY);
}
if (up.action.equals("ApplyDamage")) {
placeable.applyDamage(up.source, up.dataInt);
}
if (up.action.equals("DoneDestroying")) {
placeableDoneDestroying(placeable);
} else if (up.action.equals("InventoryUpdate")) {
Inventory i = up.inventory;
i.setTransient(registry);
placeable.setInventory(i);
} else if (up.action.equals("IsDirty")) {
placeable.setIsDirty(true);
} else if (up.action.equals("SetState")) {
placeable.setState(up.state);
}
}
} else {
if (gameController.multiplayerMode == gameController.multiplayerMode.CLIENT && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
EIError.debugMsg("Placeable not found - need " + up.id);
registry.getNetworkThread().sendData("send placeable data: " + up.id);
}
}
}
}
}
private void readObject(ObjectInputStream aInputStream) throws Exception {
aInputStream.defaultReadObject();
}
private void writeObject(ObjectOutputStream aOutputStream) throws Exception {
aOutputStream.defaultWriteObject();
}
@Override
public Object clone() {
Object ret = null;
try {
ret = super.clone();
} catch (CloneNotSupportedException e) {
}
return ret;
}
}