forked from MagicBane/Server
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
547 lines
19 KiB
547 lines
19 KiB
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . |
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· |
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ |
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ |
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ |
|
// Magicbane Emulator Project © 2013 - 2022 |
|
// www.magicbane.com |
|
|
|
|
|
package engine.objects; |
|
|
|
import engine.Enum; |
|
import engine.InterestManagement.RealmMap; |
|
import engine.InterestManagement.WorldGrid; |
|
import engine.db.archive.DataWarehouse; |
|
import engine.db.archive.RealmRecord; |
|
import engine.gameManager.BuildingManager; |
|
import engine.gameManager.DbManager; |
|
import engine.gameManager.GuildManager; |
|
import engine.gameManager.PowersManager; |
|
import engine.net.ByteBufferWriter; |
|
import engine.net.client.msg.ErrorPopupMsg; |
|
import engine.powers.PowersBase; |
|
import engine.server.MBServerStatics; |
|
import org.pmw.tinylog.Logger; |
|
|
|
import java.awt.*; |
|
import java.sql.ResultSet; |
|
import java.sql.SQLException; |
|
import java.time.LocalDateTime; |
|
import java.time.ZoneId; |
|
import java.util.HashSet; |
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import static engine.Enum.CharterType; |
|
|
|
|
|
public class Realm { |
|
|
|
// Internal class cache |
|
|
|
public static ConcurrentHashMap<Integer, Realm> _realms = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); |
|
public final int realmID; |
|
private final float mapR; //Red color |
|
private final float mapG; //Green color |
|
private final float mapB; //Blue color |
|
private final float mapA; //Alpha color |
|
private final boolean canBeClaimed; |
|
private final boolean canPlaceCities; |
|
private final int numCities; |
|
private final String realmName; |
|
private final float mapY1; |
|
private final float mapX1; |
|
private final float mapY2; |
|
private final float mapX2; |
|
private final int stretchX; |
|
private final int stretchY; |
|
private final int locX; |
|
private final int locY; |
|
private final HashSet<Integer> cities = new HashSet<>(); |
|
public Color mapColor; |
|
public LocalDateTime ruledSince; |
|
private int rulingCityUUID; |
|
private int rulingCharacterUUID; |
|
private int rulingCharacterOrdinal; |
|
private String rulingCharacterName; |
|
private int rulingNationUUID; |
|
private GuildTag rulingNationTags; |
|
private String rulingNationName; |
|
private int charterType; |
|
private String hash; |
|
|
|
/** |
|
* ResultSet Constructor |
|
*/ |
|
public Realm(ResultSet rs) throws SQLException { |
|
|
|
this.mapColor = new Color(Integer.parseInt(rs.getString("realmColor"), 16)); |
|
this.mapR = (float) (mapColor.getRed() * 0.00392156863); |
|
this.mapG = (float) (mapColor.getGreen() * 0.00392156863); |
|
this.mapB = (float) (mapColor.getBlue() * 0.00392156863); |
|
this.mapA = 1; |
|
this.canBeClaimed = rs.getBoolean("canBeClaimed"); |
|
this.canPlaceCities = rs.getBoolean("canPlaceCities"); |
|
this.numCities = rs.getInt("numCities"); |
|
this.realmName = rs.getString("realmName"); |
|
this.rulingCityUUID = rs.getInt("rulingCityUID"); |
|
this.charterType = rs.getInt("charterType"); |
|
|
|
java.sql.Timestamp ruledTimeStamp = rs.getTimestamp("ruledSince"); |
|
|
|
if (ruledTimeStamp != null) |
|
this.ruledSince = LocalDateTime.ofInstant(ruledTimeStamp.toInstant(), ZoneId.systemDefault()); |
|
|
|
this.mapY1 = rs.getFloat("mapY1"); |
|
this.mapX1 = rs.getFloat("mapX1"); |
|
this.mapY2 = rs.getFloat("mapY2"); |
|
this.mapX2 = rs.getFloat("mapX2"); |
|
this.stretchX = rs.getInt("stretchX"); |
|
this.stretchY = rs.getInt("stretchY"); |
|
this.locX = rs.getInt("locX"); |
|
this.locY = rs.getInt("locY"); |
|
this.realmID = rs.getInt("realmID"); |
|
this.hash = rs.getString("hash"); |
|
} |
|
|
|
public static void configureAllRealms() { |
|
|
|
for (Realm realm : Realm._realms.values()) { |
|
realm.configure(); |
|
} |
|
} |
|
|
|
public static Realm getRealm(int realmID) { |
|
return _realms.get(realmID); |
|
} |
|
|
|
public static boolean HasAllBlessings(PlayerCharacter claimer) { |
|
|
|
if (claimer == null) |
|
return false; |
|
|
|
PowersBase powerBlessing = PowersManager.getPowerByIDString("BLS-POWER"); |
|
if (!claimer.effects.containsKey(Integer.toString(powerBlessing.getActions().get(0).getUUID()))) |
|
return false; |
|
PowersBase wisdomBlessing = PowersManager.getPowerByIDString("BLS-POWER"); |
|
if (!claimer.effects.containsKey(Integer.toString(wisdomBlessing.getActions().get(0).getUUID()))) |
|
return false; |
|
PowersBase fortuneBlessing = PowersManager.getPowerByIDString("BLS-FORTUNE"); |
|
return claimer.effects.containsKey(Integer.toString(fortuneBlessing.getActions().get(0).getUUID())); |
|
} |
|
|
|
public static float getRealmHealthMod(City city) { |
|
Realm serverRealm; |
|
int charterType; |
|
float returnBonus = 0.0f; |
|
|
|
serverRealm = RealmMap.getRealmForCity(city); |
|
charterType = serverRealm.charterType; |
|
|
|
switch (charterType) { |
|
|
|
case 762228431: |
|
returnBonus = 0.0f; |
|
break; |
|
case -15978914: |
|
returnBonus = -.15f; |
|
break; |
|
case -600065291: |
|
returnBonus = .15f; |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
return returnBonus; |
|
} |
|
|
|
public static int getRealmMesh(City city) { |
|
Realm serverRealm; |
|
CharterType charterType; |
|
|
|
serverRealm = city.getRealm(); |
|
charterType = CharterType.getCharterTypeByID(serverRealm.charterType); |
|
|
|
return charterType.getMeshID(); |
|
} |
|
|
|
public static void loadAllRealms() { |
|
|
|
_realms = DbManager.RealmQueries.LOAD_ALL_REALMS(); |
|
|
|
} |
|
|
|
public static boolean claimRealm(PlayerCharacter player, int charterUUID) { |
|
|
|
Guild guild; |
|
Realm realm; |
|
City city; |
|
Building tol; |
|
float hPMod; |
|
Warehouse warehouse; |
|
boolean hasResources = true; |
|
int resourceValue; |
|
|
|
if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false) { |
|
ErrorPopupMsg.sendErrorPopup(player, 176); // Only guild leaders can claim a territory |
|
return false; |
|
} |
|
|
|
guild = player.getGuild(); |
|
city = guild.getOwnedCity(); |
|
|
|
if (city == null) { |
|
ErrorPopupMsg.sendErrorPopup(player, 179); // Only landed guilds may claim a territory |
|
return false; |
|
} |
|
|
|
if (city.isLocationOnCityGrid(player.getLoc()) == false) { |
|
ErrorPopupMsg.sendErrorPopup(player, 186); // Your tree is not inside a territory! |
|
return false; |
|
} |
|
|
|
tol = city.getTOL(); |
|
|
|
if (tol.getRank() != 7) { |
|
ErrorPopupMsg.sendErrorPopup(player, 181); // Your tree must be rank 7 before claiming a territory |
|
return false; |
|
} |
|
|
|
realm = RealmMap.getRealmForCity(city); |
|
|
|
if (realm.getCanBeClaimed() == false) { |
|
ErrorPopupMsg.sendErrorPopup(player, 180); // This territory cannot be ruled by anyone |
|
return false; |
|
} |
|
|
|
if (realm.isRuled() == true) { |
|
ErrorPopupMsg.sendErrorPopup(player, 178); // This territory is already claimed |
|
return false; |
|
} |
|
|
|
if (!HasAllBlessings(player)) { |
|
ErrorPopupMsg.sendErrorPopup(player, 185); // You must seek the blessing of the three sages before you can rule |
|
return false; |
|
} |
|
|
|
// Must have the required resources in warehouse to claim realm |
|
|
|
warehouse = city.getWarehouse(); |
|
|
|
if (warehouse == null) { |
|
ErrorPopupMsg.sendErrorPopup(player, 188); // You must have a warehouse to become a capital |
|
return false; |
|
} |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.GOLD); |
|
|
|
if (resourceValue < 5000000) |
|
hasResources = false; |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.STONE); |
|
|
|
if (resourceValue < 8000) |
|
hasResources = false; |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.LUMBER); |
|
|
|
if (resourceValue < 8000) |
|
hasResources = false; |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.GALVOR); |
|
|
|
if (resourceValue < 15) |
|
hasResources = false; |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.WORMWOOD); |
|
|
|
if (resourceValue < 15) |
|
hasResources = false; |
|
|
|
if (hasResources == false) { |
|
ErrorPopupMsg.sendErrorPopup(player, 184); // Insufficient gold or resources to upgrade to capital |
|
return false; |
|
} |
|
|
|
// Remove resources from warehouse before claiming realm |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.GOLD); |
|
|
|
if (DbManager.WarehouseQueries.updateGold(warehouse, resourceValue - 5000000) == true) { |
|
warehouse.resources.put(Enum.ResourceType.GOLD, resourceValue - 5000000); |
|
Warehouse.AddTransactionToWarehouse(warehouse, Enum.GameObjectType.Building, tol.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Enum.ResourceType.GOLD, 5000000); |
|
} else { |
|
Logger.error("gold update failed for warehouse of UUID:" + warehouse.getObjectUUID()); |
|
return false; |
|
} |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.STONE); |
|
|
|
if (DbManager.WarehouseQueries.updateStone(warehouse, resourceValue - 8000) == true) { |
|
warehouse.resources.put(Enum.ResourceType.STONE, resourceValue - 8000); |
|
Warehouse.AddTransactionToWarehouse(warehouse, Enum.GameObjectType.Building, tol.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Enum.ResourceType.STONE, 8000); |
|
} else { |
|
Logger.error("stone update failed for warehouse of UUID:" + warehouse.getObjectUUID()); |
|
return false; |
|
} |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.LUMBER); |
|
|
|
if (DbManager.WarehouseQueries.updateLumber(warehouse, resourceValue - 8000) == true) { |
|
warehouse.resources.put(Enum.ResourceType.LUMBER, resourceValue - 8000); |
|
Warehouse.AddTransactionToWarehouse(warehouse, Enum.GameObjectType.Building, tol.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Enum.ResourceType.LUMBER, 8000); |
|
} else { |
|
Logger.error("lumber update failed for warehouse of UUID:" + warehouse.getObjectUUID()); |
|
return false; |
|
} |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.GALVOR); |
|
|
|
if (DbManager.WarehouseQueries.updateGalvor(warehouse, resourceValue - 15) == true) { |
|
warehouse.resources.put(Enum.ResourceType.GALVOR, resourceValue - 15); |
|
Warehouse.AddTransactionToWarehouse(warehouse, Enum.GameObjectType.Building, tol.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Enum.ResourceType.GALVOR, 15); |
|
} else { |
|
Logger.error("galvor update failed for warehouse of UUID:" + warehouse.getObjectUUID()); |
|
return false; |
|
} |
|
|
|
resourceValue = warehouse.resources.get(Enum.ResourceType.WORMWOOD); |
|
|
|
if (DbManager.WarehouseQueries.updateWormwood(warehouse, resourceValue - 15) == true) { |
|
warehouse.resources.put(Enum.ResourceType.WORMWOOD, resourceValue - 15); |
|
Warehouse.AddTransactionToWarehouse(warehouse, Enum.GameObjectType.Building, tol.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Enum.ResourceType.WORMWOOD, 15); |
|
} else { |
|
Logger.error("wormwood update failed for warehouse of UUID:" + warehouse.getObjectUUID()); |
|
return false; |
|
} |
|
|
|
realm.claimRealmForCity(city, charterUUID); |
|
|
|
BuildingManager.setRank(tol, 8); |
|
WorldGrid.updateObject(tol); |
|
|
|
for (Building building : city.getParent().zoneBuildingSet) { |
|
|
|
if (building.getBlueprintUUID() != 0) { |
|
|
|
// TOL Health set through regular linear equation |
|
if (building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.TOL) { |
|
continue; |
|
} |
|
|
|
hPMod = (building.getMaxHitPoints() * getRealmHealthMod(city)); |
|
building.setMaxHitPoints(building.getMaxHitPoints() + hPMod); |
|
} |
|
} |
|
|
|
if (!guild.getNation().equals(guild)) { |
|
guild.getNation().setRealmsOwned(guild.getNation().getRealmsOwned() + 1); |
|
GuildManager.updateAllGuildTags(guild.getNation()); |
|
} |
|
|
|
guild.setRealmsOwned(guild.getRealmsOwned() + 1); |
|
GuildManager.updateAllGuildTags(guild); |
|
|
|
AbstractCharacter.removeAllBlessings(player); |
|
|
|
return true; |
|
|
|
} |
|
|
|
/* |
|
* Getters |
|
*/ |
|
public boolean isRuled() { |
|
return (this.rulingCityUUID != 0); |
|
} |
|
|
|
public boolean getCanBeClaimed() { |
|
return this.canBeClaimed; |
|
} |
|
|
|
public boolean getCanPlaceCities() { |
|
return this.canPlaceCities; |
|
} |
|
|
|
public int getNumCities() { |
|
return this.numCities; |
|
} |
|
|
|
public String getRealmName() { |
|
return this.realmName; |
|
} |
|
|
|
public City getRulingCity() { |
|
return City.getCity(this.rulingCityUUID); |
|
} |
|
|
|
|
|
// Call this after changing ownership before you serialize a realm |
|
|
|
public int getRealmID() { |
|
return this.realmID; |
|
} |
|
|
|
public void addCity(int cityUUID) { |
|
if (!this.cities.add(cityUUID)) |
|
this.cities.add(cityUUID); |
|
} |
|
|
|
public void removeCity(int cityUUID) { |
|
this.cities.remove(cityUUID); |
|
} |
|
|
|
public boolean isRealmFull() { |
|
|
|
return this.cities.size() >= this.numCities; |
|
} |
|
|
|
public boolean isRealmFullAfterBane() { |
|
|
|
return this.cities.size() > this.numCities; |
|
} |
|
|
|
public void configure() { |
|
|
|
PlayerCharacter rulingCharacter; |
|
|
|
// Configure what exactly? We won't send any of it. |
|
|
|
if (this.rulingCityUUID == 0) |
|
return; |
|
if (this.getRulingCity() == null) |
|
return; |
|
if (this.getRulingCity().getTOL() == null) |
|
return; |
|
|
|
rulingCharacter = PlayerCharacter.getPlayerCharacter(this.getRulingCity().getTOL().getOwnerUUID()); |
|
if (rulingCharacter == null) { |
|
Logger.info(this.realmName + " failed to load " + this.getRulingCity().getCityName() + " ID : " + this.rulingCityUUID); |
|
return; |
|
} |
|
|
|
this.rulingCharacterUUID = rulingCharacter.getObjectUUID(); |
|
this.rulingCharacterOrdinal = rulingCharacter.getObjectType().ordinal(); |
|
this.rulingCharacterName = rulingCharacter.getFirstName() + ' ' + rulingCharacter.getLastName(); |
|
this.rulingNationUUID = rulingCharacter.getGuild().getNation().getObjectUUID(); |
|
this.rulingNationName = rulingCharacter.getGuild().getNation().getName(); |
|
this.rulingNationTags = rulingCharacter.getGuild().getNation().getGuildTag(); |
|
} |
|
|
|
public void serializeForClientMsg(ByteBufferWriter writer) { |
|
|
|
writer.putFloat(this.mapR); |
|
writer.putFloat(this.mapG); |
|
writer.putFloat(this.mapB); |
|
writer.putFloat(this.mapA); |
|
writer.put((byte) (this.canBeClaimed ? 0x1 : 0x0)); |
|
writer.put((byte) (this.canPlaceCities ? 0x1 : 0x0)); |
|
writer.putInt(this.numCities); |
|
writer.putFloat(this.mapR); |
|
writer.putFloat(this.mapG); |
|
writer.putFloat(this.mapB); |
|
writer.putFloat(this.mapA); |
|
writer.putString(this.realmName); |
|
|
|
if (isRuled() == true) { |
|
writer.putInt(Enum.GameObjectType.Guild.ordinal()); |
|
writer.putInt(rulingNationUUID); |
|
|
|
writer.putInt(rulingCharacterOrdinal); |
|
writer.putInt(rulingCharacterUUID); |
|
|
|
writer.putInt(Enum.GameObjectType.City.ordinal()); |
|
writer.putInt(rulingCityUUID); |
|
|
|
writer.putLocalDateTime(this.ruledSince); |
|
|
|
writer.putString(rulingNationName); |
|
GuildTag._serializeForDisplay(rulingNationTags, writer); |
|
writer.putString(rulingCharacterName); |
|
writer.putInt(0xB); // Display Title: enum index starts at 10. |
|
} else { |
|
if (this.rulingCityUUID != 0) |
|
Logger.error("Failed to Load realm info for city" + this.rulingCityUUID); |
|
writer.putLong(0); |
|
writer.putLong(0); |
|
writer.putLong(0); |
|
writer.put((byte) 1); |
|
writer.put((byte) 0); |
|
writer.putInt(0x64); |
|
writer.put((byte) 0); |
|
writer.put((byte) 0); |
|
writer.put((byte) 0); |
|
writer.putInt(0); |
|
writer.putInt(0x10); |
|
writer.putInt(0x10); |
|
writer.putInt(0x10); |
|
writer.putInt(0x0); |
|
writer.putInt(0x0); |
|
writer.putInt(0); |
|
writer.putInt(0); |
|
} |
|
writer.putInt(0); // Male/Female |
|
writer.putInt(this.charterType); // Charter Type |
|
writer.putFloat(this.mapY1); |
|
writer.putFloat(this.mapX1); |
|
writer.putFloat(this.mapY2); |
|
writer.putFloat(this.mapX2); |
|
writer.putInt(this.stretchX); |
|
writer.putInt(this.stretchY); |
|
writer.putInt(this.locX); |
|
writer.putInt(this.locY); |
|
} |
|
|
|
public void updateDatabase() { |
|
DbManager.RealmQueries.REALM_UPDATE(this); |
|
} |
|
|
|
/** |
|
* @return the charterType |
|
*/ |
|
public int getCharterType() { |
|
return charterType; |
|
} |
|
|
|
public void abandonRealm() { |
|
|
|
// Push event to warehouse |
|
|
|
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.LOST); |
|
DataWarehouse.pushToWarehouse(realmRecord); |
|
|
|
// No longer own a realm |
|
this.getRulingCity().getGuild().setRealmsOwned(this.getRulingCity().getGuild().getRealmsOwned() - 1); |
|
if (!this.getRulingCity().getGuild().getNation().equals(this.getRulingCity().getGuild())) |
|
this.getRulingCity().getGuild().getNation().setRealmsOwned(this.getRulingCity().getGuild().getNation().getRealmsOwned() - 1); |
|
|
|
// Configure realm |
|
this.charterType = 0; |
|
this.rulingCityUUID = 0; |
|
this.ruledSince = null; |
|
|
|
this.updateDatabase(); |
|
} |
|
|
|
public void claimRealmForCity(City city, int charterType) { |
|
|
|
// Configure realm |
|
this.charterType = charterType; |
|
this.rulingCityUUID = city.getObjectUUID(); |
|
this.ruledSince = LocalDateTime.now(); |
|
this.configure(); |
|
this.updateDatabase(); |
|
|
|
// Push event to warehouse |
|
|
|
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.CAPTURE); |
|
DataWarehouse.pushToWarehouse(realmRecord); |
|
|
|
} |
|
|
|
public String getHash() { |
|
return hash; |
|
} |
|
|
|
}
|
|
|