/******************************************************************************* * Copyright 2015 Maximilian Stark | Dakror <mail@dakror.de> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package de.dakror.arise.game.building; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.sql.Connection; import org.json.JSONException; import org.json.JSONObject; import de.dakror.arise.game.Game; import de.dakror.arise.layer.CityHUDLayer; import de.dakror.arise.net.User; import de.dakror.arise.settings.Const; import de.dakror.arise.settings.Resources; import de.dakror.arise.settings.Resources.Resource; import de.dakror.arise.ui.BuildButton; import de.dakror.arise.util.Assistant; import de.dakror.gamesetup.ui.ClickEvent; import de.dakror.gamesetup.ui.ClickableComponent; import de.dakror.gamesetup.ui.Container; import de.dakror.gamesetup.util.Helper; /** * @author Dakror */ public abstract class Building extends ClickableComponent { public static int GRID = 32; protected int tx, ty, tw, th, id, typeId, level, maxLevel, levelFac, minCityLevel; public int bx, by, bw, bh; /** * -1 = marked for deletion<br> * 0 = construction<br> * 1 = built<br> * 2 = deconstruction<br> * 3 = upgrading<br> */ protected int stage; protected int stageChangeDuration; protected int stageChangeSecondsLeft; protected String name, desc; protected String metadata; protected Resources buildingCosts, products, scale; protected Container guiContainer; public Building(int x, int y, int width, int height, int level) { super(x * GRID, y * GRID, width * GRID, height * GRID); this.level = level; buildingCosts = new Resources(); products = new Resources(); scale = new Resources(); bx = by = 0; bw = width; bh = height; metadata = ""; guiContainer = new Container.DefaultContainer(); addClickEvent(new ClickEvent() { @Override public void trigger() { CityHUDLayer.selectedBuilding = Building.this; float duration = stageChangeDuration * Const.DECONSTRUCT_FACTOR / Game.world.getSpeed(); CityHUDLayer.upgrade.setUpgradeMode("Ausbau", "Die Stufe des Gebäudes wird erhöht. \nDauer: " + Assistant.formatSeconds((long) duration), getUpgradeCosts(), 0); CityHUDLayer.upgrade.setProducts(products); CityHUDLayer.upgrade.setScale(scale); CityHUDLayer.upgrade.setLevel(Building.this.level); CityHUDLayer.upgrade.setMaxLevel(maxLevel); CityHUDLayer.deconstruct.setUpgradeMode("Abriss", "Das Gebäudes wird abgerissen. Es werden keine Resourcen zurückgegeben.", new Resources(), 0); } }); } public int getId() { return id; } public void setId(int id) { this.id = id; } public void init() { try { if (Game.config.getJSONObject("buildings").has("" + typeId)) { JSONObject o = Game.config.getJSONObject("buildings").getJSONObject(typeId + ""); buildingCosts = new Resources(o.getJSONObject("costs")); products = new Resources(o.getJSONObject("products")); scale = new Resources(o.getJSONObject("scale")); stageChangeDuration = o.getInt("stage"); minCityLevel = o.has("mincitylevel") ? o.getInt("mincitylevel") : 0; maxLevel = o.has("maxlevel") ? o.getInt("maxlevel") : Const.BUILDING_MAX_LEVEL; levelFac = o.has("levelfac") ? o.getInt("levelfac") : Const.BUILDING_MAX_LEVEL; } } catch (JSONException e) { e.printStackTrace(); } } @Override public void draw(Graphics2D g) { if (Game.world == null) return; if (state != 0 || (CityHUDLayer.selectedBuilding != null && CityHUDLayer.selectedBuilding.equals(this))) { Color c = g.getColor(); g.setColor(Color.black); g.drawRect(x + bx * GRID - 1, y + by * GRID - 1, bw * GRID + 2, bh * GRID + 2); g.setColor(c); } if (stage > 0) drawStage1(g); if (stageChangeSecondsLeft > 0) { int tx = x + bx * GRID, ty = y + by * GRID, width = 128; if (stage == 0) Assistant.drawBuildingStage(tx, ty, this, g); Color c = g.getColor(); g.setColor(Color.white); Helper.drawHorizontallyCenteredString(Assistant.formatSeconds(stageChangeSecondsLeft), tx + (bw * GRID - width) / 2, width, ty + (bh * GRID) / 2 + 6, g, 30); g.setColor(c); } } protected void drawStage1(Graphics2D g) { Helper.setRenderingHints(g, false); Helper.drawImage2(Game.getImage("world/structs.png"), x, y, width, height, tx * 32, ty * 32, tw * 32, th * 32, g); Helper.setRenderingHints(g, true); } @Override public void drawTooltip(int x, int y, Graphics2D g) { if (Game.currentGame.getActiveLayer() instanceof CityHUDLayer) { String string = getTooltipText(); int width = g.getFontMetrics(g.getFont().deriveFont(30f)).stringWidth(string) + 30; int height = 64; int x1 = x; int y1 = y; if (x1 + width > Game.getWidth()) x1 -= (x1 + width) - Game.getWidth(); if (y1 + height > Game.getHeight()) y1 -= (y1 + height) - Game.getHeight(); Helper.drawShadow(x1, y1, width, height, g); Helper.drawString(string, x1 + 15, y1 + 40, g, 30); } } @Override public void update(int tick) { if (stageChangeSecondsLeft > 0 && tick % Game.currentGame.getUPS() == 0) stageChangeSecondsLeft--; } public String getTooltipText() { return "Lvl. " + (level + 1) + " " + name + (stage == 2 ? " (Abriss)" : (stage == 3 ? " (Ausbau)" : (stage == 0 ? " (Bau)" : ""))); } public int getTypeId() { return typeId; } public int getLevel() { return level; } public int getStage() { return stage; } public void setStage(int s) { stage = s; } public int getStageChangeSeconds() { return stageChangeDuration; } public long getStageChangeSecondsLeft() { return stageChangeSecondsLeft; } /** * @param s - time in seconds */ public void setStageChangeSecondsLeft(int s) { stageChangeSecondsLeft = s; } protected float getStageChangeDuration() { return Math.round(stageChangeDuration * (stage == 0 ? 1f : Const.DECONSTRUCT_FACTOR) / Game.world.getSpeed()); } public String getName() { return name; } public String getDescription() { return desc; } public String getData() { return typeId + ":" + level + ":" + ((x - 96) / GRID) + ":" + ((y - 96) / GRID) + ":" + stage + ":" + stageChangeSecondsLeft + (metadata.length() > 0 ? ":" + metadata : ""); } public Resources getBuildingCosts() { return buildingCosts; } public Resources getUpgradeCosts() { Resources res = new Resources(); res.add(buildingCosts); for (Resource r : res.getFilled()) res.set(r, (int) Math.round((Const.BUILDING_MAX_LEVEL / (float) levelFac) * res.get(r) * Math.pow(Const.UPGRADE_FACTOR, level + 1))); return res; } public Resources getProducts() { return products; } public int getMinCityLevel() { return minCityLevel; } public Resources getScalingProducts() { Resources p = new Resources(); p.add(products); if (level > 0) p.add(Resources.mul(scale, level)); return p; } public Resources getScale() { return scale; } public Container getGuiContainer() { return guiContainer; } public int getMaxLevel() { return maxLevel; } public void setMetadata(String s) { if (s == null) s = ""; metadata = s; } protected void addGuiButton(int x, int y, Image icon, String tooltip, String desc, Resources buildingCosts, int minCityLevel, ClickEvent action) { BuildButton b = new BuildButton(x * 56 + Game.getWidth() - 270, y * 56 + Game.getHeight() - 170, 32, 32, icon); b.addClickEvent(action); b.mode1 = true; b.setUpgradeMode(tooltip, desc, buildingCosts, minCityLevel); guiContainer.components.add(b); } protected void addGuiButton(int x, int y, Point icon, String tooltip, String desc, Resources buildingCosts, int minCityLevel, ClickEvent action) { addGuiButton(x, y, Game.getImage("system/icons.png").getSubimage(icon.x * 24, icon.y * 24, 24, 24), tooltip, desc, buildingCosts, minCityLevel, action); } /** Server-side only */ public void onSpecificChange(int cityId, User owner, Connection connection) {} @Override public boolean contains(int x, int y) { return new Rectangle(this.x + bx * GRID, this.y + by * GRID, bw * GRID, bh * GRID).contains(x, y); } public void setLevel(int newLevel) { level = newLevel; } public void updateGuiButtons() {} public static Building getBuildingByTypeId(int x, int y, int level, int typeId) { switch (typeId) { case 1: return new Center(x, y, level); case 2: return new Lumberjack(x, y, level); case 3: return new Mine(x, y, level); case 4: return new Quarry(x, y, level); case 5: return new Barracks(x, y, level); case 6: return new Barn(x, y, level); default: return null; } } }