package com.weem.epicinventor.resource;
import com.weem.epicinventor.*;
import com.weem.epicinventor.actor.*;
import com.weem.epicinventor.drop.*;
import com.weem.epicinventor.network.*;
import com.weem.epicinventor.utility.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
public class ResourceManager extends Manager implements Serializable {
protected static final long serialVersionUID = 10000L;
private HashMap<String, Resource> resources;
transient private HashMap<String, Resource> collectingResources;
private ArrayList<ResourceType> resourceTypes;
private final static String CONFIG_FILE = "Resources.dat";
transient private boolean transmitting;
public ResourceManager(GameController gc, Registry rg) {
super(gc, rg);
resources = new HashMap<String, Resource>();
collectingResources = new HashMap<String, Resource>();
resourceTypes = new ArrayList<ResourceType>();
loadResourceTypes("Resources.dat");
checkResources();
}
@Override
public void setTransient(Registry rg) {
super.setTransient(rg);
try {
for (String key : resources.keySet()) {
Resource resource = (Resource) resources.get(key);
resource.setTransient(rg, this);
}
} 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
}
for (int i = 0; i < resourceTypes.size(); i++) {
resourceTypes.get(i).setTransient(rg);
}
transmitting = false;
}
public void registerResource(Resource r) {
if (!resources.containsKey(r.getId())) {
resources.put(r.getId(), r);
}
}
private void loadResourceTypes(String fn) {
String line;
String parts[];
try {
InputStream in = getClass().getResourceAsStream(GameController.CONFIG_DIR + fn);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
int mapLevel = 1;
String name = "";
String type = "";
int qtyMin = 0;
int qtyMax = 0;
int gatherTime = 0;
int[] levels;
boolean isHeader = true;
ResourceType rt;
levels = new int[5];
while ((line = br.readLine()) != null) {
if (line.length() == 0) {
continue;
}
if (line.startsWith("//")) {
continue;
}
if (isHeader) {
parts = line.split(" ");
if (parts.length != 5) {
System.out.println("Error in " + fn + " (" + parts.length + ")");
}
name = parts[0];
type = parts[1];
qtyMin = Integer.parseInt(parts[2]);
qtyMax = Integer.parseInt(parts[3]);
gatherTime = Integer.parseInt(parts[4]);
isHeader = false;
mapLevel = 0;
levels = new int[5];
} else {
levels[mapLevel] = Integer.parseInt(line);
if (mapLevel >= 4) {
rt = new ResourceType(this, registry, name, type, qtyMin, qtyMax, gatherTime, levels);
resourceTypes.add(rt);
isHeader = true;
}
mapLevel++;
}
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
public Resource getClosest(Point p) {
Resource resource = null;
Resource closestResource = null;
double closestDistance = 0;
try {
for (String key : resources.keySet()) {
resource = (Resource) resources.get(key);
double distance = p.distance(resource.getCenterPoint());
if ((distance < closestDistance || closestDistance == 0)) {
closestResource = resource;
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 closestResource;
}
public ResourceType getResourceTypeByName(String name) {
ResourceType resourceType = null;
for (int i = 0; i < resourceTypes.size(); i++) {
resourceType = resourceTypes.get(i);
if (resourceType.getName().equals(name)) {
return resourceType;
}
}
return resourceType;
}
private void checkResources() {
int level = 0;
int needed = 0;
int[] levels;
int[] resourcesInLevels;
Resource resource = null;
ResourceType resourceType = null;
for (int i = 0; i < resourceTypes.size(); i++) {
resourceType = resourceTypes.get(i);
levels = resourceType.getLevels();
resourcesInLevels = new int[5];
try {
for (String key : resources.keySet()) {
resource = (Resource) resources.get(key);
if (resource.getResourceType() == resourceType) {
level = registry.getBlockManager().getLevelByY(resource.getMapY());
if (level >= 0 && level < levels.length) {
resourcesInLevels[level]++;
}
}
}
} 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
}
for (int x = 0; x < 5; x++) {
needed = levels[x] - resourcesInLevels[x];
if (needed > 0) {
spawnResources(resourceType, needed, x);
}
}
}
}
private void spawnResources(ResourceType rt, int count, int level) {
Point p;
int y;
for (int i = 0; i < count; i++) {
p = rt.getNewXY(gameController.getMapWidth(), level);
if (p.x > 0 && p.y > 0) {
Resource r = new Resource(registry, this, rt, p.x, p.y, 0);
y = findNextFloor(p.x + r.getWidth(), p.y, r.getHeight());
if (p.y == y) {
//make sure the resource isn't spawned in view
if (this.isInPlayerView(p) || this.isInFrontOfPlaceable(r.getPerimeter())) {
r = null;
} else {
registerResource(r);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(r);
}
}
}
}
}
}
}
public void spawnXPCrystal(int x, int y, int xp) {
Resource r = new Resource(registry, this, this.getResourceTypeByName("XPCrystal"), x, y, xp);
r.setMapY(findNextFloor(x + r.getWidth(), y, r.getHeight()));
registerResource(r);
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
registry.getNetworkThread().sendData(r);
}
}
}
@Override
public ResourceType getResourceTypeByResourceId(String id) {
if (resources.containsKey(id)) {
Resource resource = resources.get(id);
return resource.getResourceType();
} else {
return null;
}
}
public HashMap<String, Resource> getResources() {
return resources;
}
public HashMap<String, Resource> getCollectingResources() {
return collectingResources;
}
@Override
public Resource getResourceById(String id) {
if (resources.containsKey(id)) {
Resource resource = resources.get(id);
return resource;
} else {
return null;
}
}
public void stopGather(Player p) {
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
Resource resource = null;
try {
for (String key : resources.keySet()) {
resource = (Resource) resources.get(key);
if (resource != null) {
if (resource.getIsCollecting()) {
if (resource.getCollectingPlayer() == p && !resource.isNPCCollecting()) {
resource.setCollecting(p, false);
collectingResources.remove(resource.getId());
}
}
}
}
} 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
}
}
}
public void stopNPCGather(Player p) {
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
Resource resource = null;
try {
for (String key : resources.keySet()) {
resource = (Resource) resources.get(key);
if (resource != null) {
if (resource.getIsCollecting()) {
if (resource.getCollectingPlayer() == p && resource.isNPCCollecting()) {
resource.setCollecting(p, false);
collectingResources.remove(resource.getId());
}
}
}
}
} 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
}
}
}
public String startGather(Player player, Point p, int maxDistance) {
return startGather(player, p, maxDistance, false);
}
public String startGather(Player player, Point p, int maxDistance, boolean npc) {
Resource resource = null;
Resource closestResource = null;
double closestDistance = 0;
try {
for (String key : resources.keySet()) {
resource = (Resource) resources.get(key);
if (!resource.getIsCollecting()) {
//resource.setCollecting(player, false);
if (p.distance(resource.getCenterPoint()) < closestDistance || closestDistance == 0) {
closestResource = resource;
closestDistance = p.distance(resource.getCenterPoint());
}
}
}
} 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 (closestResource != null && closestDistance <= maxDistance) {
closestResource.setCollecting(player, true, npc);
collectingResources.put(closestResource.getId(), closestResource);
return closestResource.getId();
}
return "";
}
public void resourceDoneCollecting(Resource r) {
Player p = registry.getPlayerManager().getCurrentPlayer();
resourceDoneCollecting(p, r);
}
public void resourceDoneCollecting(Player p, Resource r) {
if (p != null && r != null) {
int qty = r.getResourceType().getQty();
if (r.isNPCCollecting()) {
p.npcDoneCollecting();
} else {
gameController.stopGather(p);
}
if (gameController.multiplayerMode == gameController.multiplayerMode.CLIENT && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdatePlayer up = new UpdatePlayer(p.getId());
up.action = "CollectedResource";
up.dataString = r.getId();
registry.getNetworkThread().sendData(up);
}
} else {
if (r.getXP() > 0) {
SoundClip cl = new SoundClip("Player/Good");
if (gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
p.addXP(r.getXP());
r.destroy();
}
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateResource ur = new UpdateResource(r.getId());
ur.action = "Destroy";
registry.getNetworkThread().sendData(ur);
}
}
} else {
if (gameController.playerAddItem(p, r.getResourceType().getName(), qty) == 0
|| (r.getResourceType().getQtyMin() == 0
&& r.getResourceType().getQtyMax() == 0)) {
ArrayList<Drop> drops = new ArrayList<Drop>();
if (r.getResourceType().getName().equals("Stone")) {
drops.add(new Drop(r.getResourceType().getName(), qty));
if (Rand.getRange(1, 100) <= 30) {
gameController.playerAddItem(p, "Pebble", Rand.getRange(1, 2));
drops.add(new Drop("Pebble", 1));
}
} else if (r.getResourceType().getName().equals("Wood")) {
drops.add(new Drop(r.getResourceType().getName(), qty));
if (Rand.getRange(1, 100) <= 20) {
gameController.playerAddItem(p, "Thorn", Rand.getRange(1, 1));
drops.add(new Drop("Thorn", 1));
}
if (Rand.getRange(1, 100) <= 15) {
gameController.playerAddItem(p, "Flower", Rand.getRange(1, 1));
drops.add(new Drop("Flower", 1));
}
} else if (r.getResourceType().getName().equals("Plant")) {
if (Rand.getRange(1, 100) <= 40) {
gameController.playerAddItem(p, "Thorn", Rand.getRange(1, 2));
drops.add(new Drop("Thorn", 1));
}
if (Rand.getRange(1, 100) <= 25) {
gameController.playerAddItem(p, "Web", Rand.getRange(1, 1));
drops.add(new Drop("Web", 1));
}
if (Rand.getRange(1, 100) <= 30) {
gameController.playerAddItem(p, "Flower", Rand.getRange(1, 1));
drops.add(new Drop("Flower", 1));
}
if (Rand.getRange(1, 100) <= 2) {
gameController.playerAddItem(p, "PumpkinSeed", Rand.getRange(1, 2));
drops.add(new Drop("PumpkinSeed", 1));
}
if (Rand.getRange(1, 100) <= 5) {
gameController.playerAddItem(p, "WheatSeed", Rand.getRange(1, 2));
drops.add(new Drop("WheatSeed", 1));
}
} else {
drops.add(new Drop(r.getResourceType().getName(), qty));
}
if (p == registry.getPlayerManager().getCurrentPlayer()) {
registry.getIndicatorManager().createIndicator(registry.getPlayerManager().getCurrentPlayer().getMapX() + (registry.getPlayerManager().getCurrentPlayer().getWidth() / 2), registry.getPlayerManager().getCurrentPlayer().getMapY() + 32, drops);
} else {
if (registry.getGameController().multiplayerMode != registry.getGameController().multiplayerMode.CLIENT) {
}
}
r.destroy();
if (gameController.multiplayerMode == gameController.multiplayerMode.SERVER && registry.getNetworkThread() != null) {
if (registry.getNetworkThread().readyForUpdates()) {
UpdateResource ur = new UpdateResource(r.getId());
ur.action = "Destroy";
registry.getNetworkThread().sendData(ur);
}
}
if (registry.getPlayerManager().getCurrentPlayer() == p) {
SoundClip cl = new SoundClip("Player/Good");
}
}
}
}
}
}
@Override
public void update() {
if (!transmitting) {
super.update();
boolean resourcesUpdated = false;
Resource resource = null;
ArrayList dirtyResources = new ArrayList();
try {
for (String key : resources.keySet()) {
resource = (Resource) resources.get(key);
if (resource != null) {
resource.update();
if (resource.isDirty()) {
dirtyResources.add(key);
}
}
}
} 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 (dirtyResources.size() > 0) {
resourcesUpdated = true;
for (int i = 0; i < dirtyResources.size(); i++) {
resources.remove((String) dirtyResources.get(i));
}
}
if (resourcesUpdated && gameController.multiplayerMode != gameController.multiplayerMode.CLIENT) {
checkResources();
}
}
}
public void render(Graphics g) {
if (!transmitting) {
Resource resource = null;
try {
for (String key : resources.keySet()) {
resource = (Resource) resources.get(key);
resource.render(g);
}
} 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
}
}
}
public void renderMiniMapResources(Graphics g, int mx, int my, int cx, int cy, int w, int h, int x, int y, String resourceName) {
HashMap<String, Resource> rs = new HashMap<String, Resource>(resources);
Resource resource = null;
int[] xy = null;
try {
for (String key : rs.keySet()) {
resource = (Resource) rs.get(key);
if (resource.getResourceType().getName().equals(resourceName) || resourceName.equals("")) {
xy = registry.getBlockManager().getMiniMapPosition(mx, my, cx, cy, w, h, resource.getMapX() / this.gameController.getBlockWidth(), resource.getMapY() / this.gameController.getBlockHeight());
if ((xy[0] > mx && xy[0] < mx + w) && (xy[1] > my + 1 && xy[1] < my + h)) {
renderMiniMapResource(g, xy[0], xy[1]);
}
}
}
} catch (Exception e) {
}
}
private void renderMiniMapResource(Graphics g, int x, int y) {
g.setColor(Color.black);
g.fillRect(x - 5, y - 7, 7, 7);
g.setColor(Color.red);
g.fillRect(x - 4, y - 6, 5, 5);
}
public void processResourceUpdateUDP(UDPResource up) {
if (up != null) {
if (resources.containsKey(up.id)) {
Resource resource = resources.get(up.id);
if (resource != null) {
resource.processUpdate(up);
}
}
}
}
public void processResourceUpdate(UpdateResource ur) {
if (ur != null) {
if (resources.containsKey(ur.id)) {
Resource resource = resources.get(ur.id);
if (resource != null) {
EIError.debugMsg(ur.id + " (" + ur.action + ")");
if (ur.action.equals("Destroy")) {
resource.destroy();
}
}
}
}
}
private void readObject(ObjectInputStream aInputStream) throws Exception {
aInputStream.defaultReadObject();
}
private void writeObject(ObjectOutputStream aOutputStream) throws Exception {
transmitting = true;
aOutputStream.defaultWriteObject();
transmitting = false;
}
}