@Override public void undoFromTemplate() { if (this.nextWallBuilt == null) { for (BlockCoord coord : wallBlocks.keySet()) { WallBlock wb = wallBlocks.get(coord); ItemManager.setTypeId(coord.getBlock(), wb.getOldId()); ItemManager.setData(coord.getBlock(), wb.getOldData()); try { wb.delete(); } catch (SQLException e) { e.printStackTrace(); } } // Remove this wall chunk. ChunkCoord coord = new ChunkCoord(this.getCorner()); CivGlobal.removeWallChunk(this, coord); } else { try { this.nextWallBuilt.processUndo(); } catch (CivException e) { e.printStackTrace(); } } }
@Override public void process() { double rate = this.getDouble("value"); int duration = Integer.valueOf(this.getString("duration")); CivGlobal.getSessionDB() .add( getKey(this.getParentTown()), rate + ":" + duration, this.getParentTown().getCiv().getId(), this.getParentTown().getId(), 0); DecimalFormat df = new DecimalFormat(); if (rate > 1.0) { sendMessage( "Our production rate has increased by " + df.format((rate - 1.0) * 100) + "% due to an unforseen event!"); } else { sendMessage( "Our production rate has decreased by " + df.format((1.0 - rate) * 100) + "% due to an unforseen event!"); } }
private void validateBlockLocation(Player player, Location loc) throws CivException { Block b = loc.getBlock(); if (ItemManager.getId(b) == CivData.CHEST) { throw new CivException("Cannot build here, would destroy chest."); } TownChunk tc = CivGlobal.getTownChunk(b.getLocation()); if (tc != null && !tc.perms.hasPermission(PlotPermissions.Type.DESTROY, CivGlobal.getResident(player))) { // Make sure we have permission to destroy any block in this area. throw new CivException( "Cannot build here, you need DESTROY permissions to the block at " + b.getX() + "," + b.getY() + "," + b.getZ()); } BlockCoord coord = new BlockCoord(b); // not building a trade outpost, prevent protected blocks from being destroyed. if (CivGlobal.getProtectedBlock(coord) != null) { throw new CivException("Cannot build here, protected blocks in the way."); } if (CivGlobal.getStructureBlock(coord) != null) { throw new CivException("Cannot build here, structure blocks in the way at " + coord); } if (CivGlobal.getFarmChunk(new ChunkCoord(coord.getLocation())) != null) { throw new CivException("Cannot build here, in the same chunk as a farm improvement."); } if (loc.getBlockY() >= Wall.MAX_HEIGHT) { throw new CivException("Cannot build here, wall is too high."); } if (loc.getBlockY() <= 1) { throw new CivException("Cannot build here, too close to bedrock."); } BlockCoord bcoord = new BlockCoord(loc); for (int y = 0; y < 256; y++) { bcoord.setY(y); StructureBlock sb = CivGlobal.getStructureBlock(bcoord); if (sb != null) { throw new CivException( "Cannot build here, this wall segment overlaps with a structure block belonging to a " + sb.getOwner().getName() + " structure."); } } }
@Override public void delete() throws SQLException { if (this.wallBlocks != null) { for (WallBlock wb : this.wallBlocks.values()) { wb.delete(); } } if (wallChunks != null) { for (ChunkCoord coord : wallChunks) { CivGlobal.removeWallChunk(this, coord); } } super.delete(); }
private boolean isValidWall() { for (WallBlock block : this.wallBlocks.values()) { BlockCoord bcoord = new BlockCoord(block.getCoord()); for (int y = 0; y < 256; y++) { bcoord.setY(y); StructureBlock sb = CivGlobal.getStructureBlock(bcoord); if (sb != null) { if (sb.getOwner() != this) { return false; } } } } return true; }
public void onHit() { // launchExplodeFirework(loc); int radius = (int) yield; HashSet<Buildable> structuresHit = new HashSet<Buildable>(); for (int x = -radius; x < radius; x++) { for (int z = -radius; z < radius; z++) { for (int y = -radius; y < radius; y++) { Block b = loc.getBlock().getRelative(x, y, z); if (ItemManager.getId(b) == CivData.BEDROCK) { continue; } if (loc.distance(b.getLocation()) <= yield) { bcoord.setFromLocation(b.getLocation()); StructureBlock sb = CivGlobal.getStructureBlock(bcoord); CampBlock cb = CivGlobal.getCampBlock(bcoord); if (sb == null && cb == null) { explodeBlock(b); continue; } if (sb != null) { if (!sb.isDamageable()) { continue; } if (sb.getOwner() instanceof TownHall) { TownHall th = (TownHall) sb.getOwner(); if (th.getControlPoints().containsKey(bcoord)) { continue; } } if (!sb.getOwner().isDestroyed()) { if (!structuresHit.contains(sb.getOwner())) { structuresHit.add(sb.getOwner()); if (sb.getOwner() instanceof TownHall) { TownHall th = (TownHall) sb.getOwner(); if (th.getHitpoints() == 0) { explodeBlock(b); } else { th.onCannonDamage(cannon.getDamage()); } } else { Player player = null; try { player = CivGlobal.getPlayer(whoFired); } catch (CivException e) { } if (!sb.getCiv().getDiplomacyManager().atWarWith(whoFired.getCiv())) { if (player != null) { CivMessage.sendError( player, "Cannot damage structures in civilizations we're not at war with."); return; } } sb.getOwner() .onDamage(cannon.getDamage(), b.getWorld(), player, sb.getCoord(), sb); CivMessage.sendCiv( sb.getCiv(), CivColor.Yellow + "Our " + sb.getOwner().getDisplayName() + " at (" + sb.getOwner().getCenterLocation().getX() + "," + sb.getOwner().getCenterLocation().getY() + "," + sb.getOwner().getCenterLocation().getZ() + ")" + " was hit by a cannon! (" + sb.getOwner().getHitpoints() + "/" + sb.getOwner().getMaxHitPoints() + ")"); } CivMessage.sendCiv( whoFired.getCiv(), CivColor.LightGreen + "We've hit " + sb.getOwner().getTown().getName() + "'s " + sb.getOwner().getDisplayName() + " with a cannon!" + " (" + sb.getOwner().getHitpoints() + "/" + sb.getOwner().getMaxHitPoints() + ")"); } } else { if (!IronCannon.cannonBlocks.containsKey(bcoord)) { explodeBlock(b); } } continue; } } } } } /* Instantly kill any players caught in the blast. */ LinkedList<Entity> players = EntityProximity.getNearbyEntities(null, loc, yield, EntityPlayer.class); for (Entity e : players) { Player player = (Player) e; player.damage(playerDamage); if (player.isDead()) { CivMessage.global( CivColor.LightGray + whoFired.getName() + " obliterated " + player.getName() + " with a cannon blast!"); } } }
private int buildWallSegment( Player player, BlockCoord first, BlockCoord second, int blockCount, HashMap<String, SimpleBlock> simpleBlocks, int verticalSegments) throws CivException { Location locFirst = first.getLocation(); Location locSecond = second.getLocation(); Vector dir = new Vector( locFirst.getX() - locSecond.getX(), locFirst.getY() - locSecond.getY(), locFirst.getZ() - locSecond.getZ()); dir.normalize(); dir.multiply(0.5); HashMap<String, SimpleBlock> thisWallBlocks = new HashMap<String, SimpleBlock>(); this.getTown().lastBuildableBuilt = null; getVerticalWallSegment(player, locSecond, thisWallBlocks); simpleBlocks.putAll(thisWallBlocks); verticalSegments++; double distance = locSecond.distance(locFirst); BlockCoord lastBlockCoord = new BlockCoord(locSecond); BlockCoord currentBlockCoord = new BlockCoord(locSecond); while (locSecond.distance(locFirst) > 1.0) { locSecond.add(dir); ChunkCoord coord = new ChunkCoord(locSecond); CivGlobal.addWallChunk(this, coord); currentBlockCoord.setFromLocation(locSecond); if (lastBlockCoord.equals(currentBlockCoord)) { continue; } else { lastBlockCoord.setFromLocation(locSecond); } blockCount++; if (blockCount > Wall.RECURSION_LIMIT) { throw new CivException( "ERROR: Building wall blocks exceeded recusion limit! Halted to keep server alive."); } getVerticalWallSegment(player, locSecond, thisWallBlocks); simpleBlocks.putAll(thisWallBlocks); verticalSegments++; // Distance should always be going down, as a failsave // check that it is. Abort if our distance goes up. double tmpDist = locSecond.distance(locFirst); if (tmpDist > distance) { break; } } /* build the last wall segment. */ if (!wallBlocks.containsKey(new BlockCoord(locFirst))) { try { getVerticalWallSegment(player, locFirst, thisWallBlocks); simpleBlocks.putAll(thisWallBlocks); verticalSegments++; } catch (CivException e) { CivLog.warning("Couldn't build the last wall segment, oh well."); } } for (SimpleBlock sb : simpleBlocks.values()) { BlockCoord bcoord = new BlockCoord(sb); int old_id = ItemManager.getId(bcoord.getBlock()); int old_data = ItemManager.getData(bcoord.getBlock()); if (!wallBlocks.containsKey(bcoord)) { try { WallBlock wb = new WallBlock(bcoord, this, old_id, old_data, sb.getType(), sb.getData()); wallBlocks.put(bcoord, wb); this.addStructureBlock(bcoord, true); wb.save(); } catch (SQLException e) { e.printStackTrace(); } } } return verticalSegments; }
@Override public void onMarkerPlacement(Player player, Location next, ArrayList<Location> locs) throws CivException { BlockCoord first = new BlockCoord(next); BlockCoord second = null; CultureChunk cc = CivGlobal.getCultureChunk(next); if (cc == null || cc.getTown().getCiv() != this.getTown().getCiv()) { throw new CivException("Cannot build here, you need to build inside your culture."); } if (locs.size() <= 1) { CivMessage.send( player, CivColor.LightGray + "First location placed, place another to start building a wall."); return; } // Validate our locations if (locs.get(0).distance(locs.get(1)) > Wall.MAX_SEGMENT) { throw new CivException( "Can only build a wall in " + Wall.MAX_SEGMENT + " block segments, pick a closer location"); } second = new BlockCoord(locs.get(0)); locs.clear(); MarkerPlacementManager.removeFromPlacementMode(player, false); Location secondLoc = second.getLocation(); // Setting to a new block coord so we can increment in buildWallSegment without changing the // corner. this.setCorner(new BlockCoord(secondLoc)); this.setComplete(true); this.save(); // We should now be able to draw a line between these two block points. HashMap<String, SimpleBlock> simpleBlocks = new HashMap<String, SimpleBlock>(); int verticalSegments = this.buildWallSegment(player, first, second, 0, simpleBlocks, 0); // Pay the piper double cost = verticalSegments * COST_PER_SEGMENT; if (!this.getTown().getTreasury().hasEnough(cost)) { for (WallBlock wb : this.wallBlocks.values()) { try { wb.delete(); } catch (SQLException e) { e.printStackTrace(); } } this.wallBlocks.clear(); throw new CivException( "Cannot build, not enough coins to pay " + cost + " coins for wall of length " + verticalSegments + " blocks."); } this.getTown().getTreasury().withdraw(cost); CivMessage.sendTown( this.getTown(), CivColor.Yellow + "Paid " + cost + " coins for " + verticalSegments + " wall segments."); // build the blocks for (SimpleBlock sb : simpleBlocks.values()) { BlockCoord bcoord = new BlockCoord(sb); ItemManager.setTypeId(bcoord.getBlock(), sb.getType()); ItemManager.setData(bcoord.getBlock(), sb.getData()); } // Add wall to town and global tables this.getTown().addStructure(this); CivGlobal.addStructure(this); this.getTown().lastBuildableBuilt = this; }