Compare commits
218
Commits
No files matched your search
@@ -11,6 +11,7 @@ package engine.InterestManagement;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector2f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.Zone;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -46,7 +47,7 @@ public class Terrain {
|
||||
// Configure PLANAR zones to use the same 16x16 pixel image
|
||||
// that all similar terrains share. (See JSON)
|
||||
|
||||
if (this.zone.template.terrain_type.equals("PLANAR"))
|
||||
if (this.zone.template.terrain_type == mbEnums.TerrainGenType.PLANAR)
|
||||
this.heightmap = 1006300; // all 0
|
||||
|
||||
// Load pixel data for this terrain from cache
|
||||
@@ -71,8 +72,8 @@ public class Terrain {
|
||||
// the blending area between child and parent terrains when
|
||||
// they are stitched together.
|
||||
|
||||
this.blend_values.x = this.zone.template.max_blend;
|
||||
this.blend_values.y = this.zone.template.min_blend;
|
||||
this.blend_values.x = this.zone.template.zone_max_blend;
|
||||
this.blend_values.y = this.zone.template.zone_min_blend;
|
||||
|
||||
Vector2f major_blend = new Vector2f(this.blend_values.x / this.zone.major_radius,
|
||||
this.blend_values.y / this.zone.major_radius);
|
||||
@@ -217,8 +218,8 @@ public class Terrain {
|
||||
|
||||
// Normalize terrain offset
|
||||
|
||||
Vector2f normalizedOffset = new Vector2f(Math.abs(zone_offset.x) / this.zone.template.major_radius,
|
||||
Math.abs(zone_offset.y) / this.zone.template.minor_radius);
|
||||
Vector2f normalizedOffset = new Vector2f(Math.abs(zone_offset.x) / this.zone.template.zone_major_radius,
|
||||
Math.abs(zone_offset.y) / this.zone.template.zone_minor_radius);
|
||||
|
||||
float blendCoefficient;
|
||||
|
||||
|
||||
@@ -118,11 +118,6 @@ public class WorldGrid {
|
||||
return outbound;
|
||||
}
|
||||
|
||||
public static HashSet<AbstractWorldObject> getObjectsInRangePartialNecroPets(Vector3fImmutable loc, double r) {
|
||||
HashSet<AbstractWorldObject> outbound = new HashSet<>();
|
||||
return outbound;
|
||||
}
|
||||
|
||||
public static HashSet<AbstractWorldObject> getObjectsInRangeContains(Vector3fImmutable loc, double r, int mask) {
|
||||
HashSet<AbstractWorldObject> outbound = getObjectsInRangePartial(loc, r, mask);
|
||||
return outbound;
|
||||
|
||||
@@ -280,7 +280,7 @@ public class PvpRecord extends DataRecord {
|
||||
outStatement.setString(7, DataWarehouse.hasher.encrypt(victimGuild.getNation().getObjectUUID()));
|
||||
outStatement.setInt(8, this.victim.getLevel());
|
||||
|
||||
outStatement.setString(9, DataWarehouse.hasher.encrypt(zone.getObjectUUID()));
|
||||
outStatement.setString(9, DataWarehouse.hasher.encryptObjectID(zone.getObjectUUID()));
|
||||
outStatement.setString(10, zone.zoneName);
|
||||
outStatement.setFloat(11, this.location.getX());
|
||||
outStatement.setFloat(12, -this.location.getZ()); // flip sign on 'y' coordinate
|
||||
|
||||
@@ -13,13 +13,7 @@ import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.BaseClass;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class dbBaseClassHandler extends dbHandlerBase {
|
||||
|
||||
@@ -33,59 +27,6 @@ public class dbBaseClassHandler extends dbHandlerBase {
|
||||
if (id == 0)
|
||||
return null;
|
||||
|
||||
BaseClass baseClass = (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id);
|
||||
|
||||
if (baseClass != null)
|
||||
return baseClass;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `obj_account` WHERE `UID`=?")) {
|
||||
|
||||
preparedStatement.setLong(1, id);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
baseClass = (BaseClass) getObjectFromRs(rs);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return baseClass;
|
||||
}
|
||||
|
||||
public ArrayList<BaseClass> GET_BASECLASS_FOR_RACE(final int id) {
|
||||
|
||||
ArrayList<BaseClass> baseClasses = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT b.* FROM `static_rune_baseclass` b, `static_rune_racebaseclass` r WHERE b.`ID` = r.`BaseClassID` && r.`RaceID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, id);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
baseClasses = getObjectsFromRs(rs, 20);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return baseClasses;
|
||||
}
|
||||
|
||||
public ArrayList<BaseClass> GET_ALL_BASE_CLASSES() {
|
||||
|
||||
ArrayList<BaseClass> baseClasses = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_baseclass`;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
baseClasses = getObjectsFromRs(rs, 20);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return baseClasses;
|
||||
return (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class dbBuildingHandler extends dbHandlerBase {
|
||||
@@ -37,56 +38,55 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public Building CREATE_BUILDING(int parentZoneID, int OwnerUUID, String name, int meshUUID,
|
||||
Vector3fImmutable location, float meshScale, int currentHP,
|
||||
ProtectionState protectionState, int currentGold, int rank,
|
||||
DateTime upgradeDate, int blueprintUUID, float w, float rotY) {
|
||||
public int PERSIST(Building building) {
|
||||
|
||||
Building building = null;
|
||||
int objectUUID = 0;
|
||||
|
||||
if (DbManager.refuseStaticWrite(building))
|
||||
return 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("CALL `building_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?);")) {
|
||||
|
||||
preparedStatement.setInt(1, parentZoneID);
|
||||
preparedStatement.setInt(2, OwnerUUID);
|
||||
preparedStatement.setString(3, name);
|
||||
preparedStatement.setInt(4, meshUUID);
|
||||
preparedStatement.setFloat(5, location.x);
|
||||
preparedStatement.setFloat(6, location.y);
|
||||
preparedStatement.setFloat(7, location.z);
|
||||
preparedStatement.setFloat(8, meshScale);
|
||||
preparedStatement.setInt(9, currentHP);
|
||||
preparedStatement.setString(10, protectionState.name());
|
||||
preparedStatement.setInt(11, currentGold);
|
||||
preparedStatement.setInt(12, rank);
|
||||
preparedStatement.setInt(1, building.parentZoneUUID);
|
||||
preparedStatement.setInt(2, building.getOwnerUUID());
|
||||
preparedStatement.setString(3, building.getName());
|
||||
preparedStatement.setInt(4, building.meshUUID);
|
||||
preparedStatement.setFloat(5, building.statLat);
|
||||
preparedStatement.setFloat(6, building.statAlt);
|
||||
preparedStatement.setFloat(7, building.statLon);
|
||||
preparedStatement.setFloat(8, building.getMeshScale().x);
|
||||
preparedStatement.setInt(9, (int) building.getHealth());
|
||||
preparedStatement.setString(10, building.getProtectionState().name());
|
||||
preparedStatement.setInt(11, building.getStrongboxValue());
|
||||
preparedStatement.setInt(12, building.getRank());
|
||||
|
||||
if (upgradeDate != null)
|
||||
preparedStatement.setTimestamp(13, new java.sql.Timestamp(upgradeDate.getMillis()));
|
||||
if (building.upgradeDateTime != null)
|
||||
preparedStatement.setTimestamp(13, java.sql.Timestamp.valueOf(building.upgradeDateTime));
|
||||
else
|
||||
preparedStatement.setNull(13, java.sql.Types.DATE);
|
||||
|
||||
preparedStatement.setInt(14, blueprintUUID);
|
||||
preparedStatement.setFloat(15, w);
|
||||
preparedStatement.setFloat(16, rotY);
|
||||
preparedStatement.setInt(14, building.getBlueprintUUID());
|
||||
preparedStatement.setFloat(15, building.getRotation().w);
|
||||
preparedStatement.setFloat(16, building.getRotation().y);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
if (rs.next()) {
|
||||
int objectUUID = (int) rs.getLong("UID");
|
||||
|
||||
if (objectUUID > 0)
|
||||
building = GET_BUILDINGBYUUID(objectUUID);
|
||||
}
|
||||
if (rs.next())
|
||||
objectUUID = (int) rs.getLong("UID");
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return building;
|
||||
return objectUUID;
|
||||
}
|
||||
|
||||
public boolean DELETE_FROM_DATABASE(final Building b) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(b))
|
||||
return false;
|
||||
|
||||
return removeFromBuildings(b);
|
||||
}
|
||||
|
||||
@@ -107,6 +107,26 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
return buildings;
|
||||
}
|
||||
|
||||
public HashSet<Integer> GET_NPC_BUILDING_OWNERS() {
|
||||
|
||||
HashSet<Integer> npcOwners = new HashSet<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT DISTINCT `obj_building`.`ownerUUID` FROM `obj_building` INNER JOIN `object` ON `object`.`UID` = `obj_building`.`ownerUUID` WHERE `object`.`type` = 'npc';")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
npcOwners.add(rs.getInt("ownerUUID"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("read: " + npcOwners.size() + " NPC building owners");
|
||||
return npcOwners;
|
||||
}
|
||||
|
||||
public Building GET_BUILDINGBYUUID(int uuid) {
|
||||
|
||||
if (uuid == 0)
|
||||
@@ -157,6 +177,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
String result = "";
|
||||
|
||||
if (DbManager.refuseStaticWrite(b))
|
||||
return result;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("CALL building_SETPROP(?,?,?)")) {
|
||||
|
||||
@@ -180,6 +203,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
int rowCount;
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `object` INNER JOIN `obj_building` On `object`.`UID` = `obj_building`.`UID` SET `object`.`parent`=?, `obj_building`.`locationX`=?, `obj_building`.`locationY`=?, `obj_building`.`locationZ`=? WHERE `obj_building`.`UID`=?;")) {
|
||||
|
||||
@@ -200,23 +226,14 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
}
|
||||
|
||||
private boolean removeFromBuildings(final Building b) {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `object` WHERE `UID` = ?")) {
|
||||
|
||||
preparedStatement.setLong(1, b.getObjectUUID());
|
||||
preparedStatement.execute();
|
||||
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
return deleteObjectTree(b.getObjectUUID(), null) >= 0;
|
||||
}
|
||||
|
||||
public boolean CHANGE_NAME(Building b, String newName) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(b))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `name`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -233,6 +250,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean SET_RESERVE(Building b, int reserveAmount) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(b))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `reserve`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -251,6 +271,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
//CAS update to rank
|
||||
public boolean CHANGE_RANK(final long buildingID, int newRank) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `rank`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -267,6 +290,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_BUILDING_HEALTH(final long buildingID, int NewHealth) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `currentHP`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -283,6 +309,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_BUILDING_ALTITUDE(final long buildingID, float newAltitude) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `locationY`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -299,6 +328,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_PROTECTIONSTATE(final long buildingUUID, ProtectionState protectionState) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingUUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `protectionState`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -315,6 +347,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_DOOR_LOCK(final int buildingUUID, int doorFlags) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingUUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET doorState = ? WHERE UID = ?")) {
|
||||
|
||||
@@ -331,6 +366,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean ADD_TO_FRIENDS_LIST(final long buildingID, final long friendID, final long guildID, final int friendType) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_building_friends` (`buildingUID`, `playerUID`,`guildUID`, `friendType`) VALUES (?,?,?,?)")) {
|
||||
|
||||
@@ -349,6 +387,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean REMOVE_FROM_FRIENDS_LIST(final long buildingID, long friendID, long guildID, int friendType) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_building_friends` WHERE `buildingUID`=? AND `playerUID`=? AND `guildUID` =? AND `friendType` = ?")) {
|
||||
|
||||
@@ -367,6 +408,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean REMOVE_FROM_CONDEMNED_LIST(final long buildingID, long friendID, long guildID, int friendType) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_building_condemned` WHERE `buildingUID`=? AND `playerUID`=? AND `guildUID` =? AND `friendType` = ?")) {
|
||||
|
||||
@@ -385,6 +429,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public void CLEAR_FRIENDS_LIST(final long buildingID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_building_friends` WHERE `buildingUID`=?")) {
|
||||
|
||||
@@ -399,6 +446,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public void CLEAR_CONDEMNED_LIST(final long buildingID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_building_condemned` WHERE `buildingUID`=?")) {
|
||||
|
||||
@@ -413,6 +463,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean CLEAR_PATROL(final long buildingID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, buildingID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_building_patrol_points` WHERE `buildingUID`=?")) {
|
||||
|
||||
@@ -514,6 +567,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean ADD_TO_CONDEMNLIST(final long parentUID, final long playerUID, final long guildID, final int friendType) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, parentUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_building_condemned` (`buildingUID`, `playerUID`,`guildUID`, `friendType`) VALUES (?,?,?,?)")) {
|
||||
|
||||
@@ -532,6 +588,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean ADD_TO_PATROL(final long parentUID, final Vector3fImmutable patrolPoint) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, parentUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_building_patrol_points` (`buildingUID`, `patrolX`,`patrolY`, `patrolZ`) VALUES (?,?,?,?)")) {
|
||||
|
||||
@@ -677,6 +736,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateBuildingRank(final Building b, int Rank) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(b))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `rank`=?,"
|
||||
+ "`upgradeDate`=?, `meshUUID`=?, `currentHP`=? "
|
||||
@@ -698,6 +760,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateReverseKOS(final Building b, boolean reverse) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(b))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `reverseKOS`=? WHERE `UID` = ?")) {
|
||||
|
||||
@@ -714,6 +779,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateActiveCondemn(final Condemned condemn, boolean active) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Building, condemn.buildingUUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_building_condemned` SET `active`=? "
|
||||
+ "WHERE`buildingUID` = ? AND `playerUID` = ? AND `guildUID` = ? AND `friendType` = ?")) {
|
||||
@@ -734,6 +802,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateBuildingOwner(final Building building, int ownerUUID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(building))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_building` SET `ownerUUID`=? "
|
||||
+ " WHERE `UID` = ?")) {
|
||||
@@ -751,6 +822,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateBuildingUpgradeTime(LocalDateTime upgradeDateTime, Building toUpgrade, int costToUpgrade) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(toUpgrade))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET upgradeDate=?, currentGold=? "
|
||||
+ "WHERE UID = ?")) {
|
||||
@@ -774,6 +848,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateMaintDate(Building building) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(building))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET maintDate=? "
|
||||
+ "WHERE UID = ?")) {
|
||||
@@ -795,6 +872,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean addTaxes(Building building, TaxType taxType, int amount, boolean enforceKOS) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(building))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET taxType=?, taxAmount = ?, enforceKOS = ? "
|
||||
+ "WHERE UID = ?")) {
|
||||
@@ -814,6 +894,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean removeTaxes(Building building) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(building))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET taxType=?, taxAmount = ?, enforceKOS = ?, taxDate = ? "
|
||||
+ "WHERE UID = ?")) {
|
||||
@@ -834,6 +917,9 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
public boolean acceptTaxes(Building building) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(building))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET taxDate=? "
|
||||
+ "WHERE UID = ?")) {
|
||||
|
||||
@@ -139,6 +139,9 @@ public class dbCityHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateforceRename(City city, boolean value) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(city))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_city` SET `forceRename`=?"
|
||||
+ " WHERE `UID` = ?")) {
|
||||
@@ -156,6 +159,9 @@ public class dbCityHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateOpenCity(City city, boolean value) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(city))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_city` SET `open`=?"
|
||||
+ " WHERE `UID` = ?")) {
|
||||
@@ -173,6 +179,9 @@ public class dbCityHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateTOL(City city, int tolID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(city))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_city` SET `treeOfLifeUUID`=?"
|
||||
+ " WHERE `UID` = ?")) {
|
||||
@@ -191,6 +200,9 @@ public class dbCityHandler extends dbHandlerBase {
|
||||
|
||||
public boolean renameCity(City city, String name) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(city))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_city` SET `name`=?"
|
||||
+ " WHERE `UID` = ?")) {
|
||||
@@ -209,6 +221,9 @@ public class dbCityHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateSiegesWithstood(City city, int value) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(city))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_city` SET `name`=?"
|
||||
+ " WHERE `UID` = ?")) {
|
||||
@@ -227,6 +242,9 @@ public class dbCityHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateRealmTaxDate(City city, LocalDateTime localDateTime) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(city))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_city` SET `realmTaxDate` =?"
|
||||
+ " WHERE `UID` = ?")) {
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.mbEnums;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.effectmodifiers.*;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class dbEffectsBaseHandler extends dbHandlerBase {
|
||||
|
||||
public dbEffectsBaseHandler() {
|
||||
|
||||
}
|
||||
|
||||
public static ArrayList<EffectsBase> getAllEffectsBase() {
|
||||
|
||||
ArrayList<EffectsBase> effectList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement prepareStatement = connection.prepareStatement("SELECT * FROM static_power_effectbase ORDER BY `IDString` DESC")) {
|
||||
|
||||
ResultSet rs = prepareStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
EffectsBase effectBase = new EffectsBase(rs);
|
||||
effectList.add(effectBase);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e.toString());
|
||||
}
|
||||
|
||||
return effectList;
|
||||
}
|
||||
|
||||
public static void cacheAllEffectModifiers() {
|
||||
|
||||
String IDString;
|
||||
AbstractEffectModifier abstractEffectModifier = null;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement prepareStatement = connection.prepareStatement("SELECT * FROM static_power_effectmod")) {
|
||||
|
||||
ResultSet rs = prepareStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
IDString = rs.getString("IDString");
|
||||
EffectsBase effectBase = PowersManager.getEffectByIDString(IDString);
|
||||
mbEnums.ModType modifier = mbEnums.ModType.GetModType(rs.getString("modType"));
|
||||
|
||||
//combine item prefix and suffix effect modifiers
|
||||
|
||||
abstractEffectModifier = getCombinedModifiers(abstractEffectModifier, rs, effectBase, modifier);
|
||||
|
||||
if (abstractEffectModifier != null) {
|
||||
|
||||
if (EffectsBase.modifiersMap.containsKey(effectBase.getIDString()) == false)
|
||||
EffectsBase.modifiersMap.put(effectBase.getIDString(), new HashSet<>());
|
||||
|
||||
EffectsBase.modifiersMap.get(effectBase.getIDString()).add(abstractEffectModifier);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static AbstractEffectModifier getCombinedModifiers(AbstractEffectModifier abstractEffectModifier, ResultSet rs, EffectsBase effectBase, mbEnums.ModType modifier) throws SQLException {
|
||||
switch (modifier) {
|
||||
case AdjustAboveDmgCap:
|
||||
abstractEffectModifier = new AdjustAboveDmgCapEffectModifier(rs);
|
||||
break;
|
||||
case Ambidexterity:
|
||||
abstractEffectModifier = new AmbidexterityEffectModifier(rs);
|
||||
break;
|
||||
case AnimOverride:
|
||||
break;
|
||||
case ArmorPiercing:
|
||||
abstractEffectModifier = new ArmorPiercingEffectModifier(rs);
|
||||
break;
|
||||
case AttackDelay:
|
||||
abstractEffectModifier = new AttackDelayEffectModifier(rs);
|
||||
break;
|
||||
case Attr:
|
||||
abstractEffectModifier = new AttributeEffectModifier(rs);
|
||||
break;
|
||||
case BlackMantle:
|
||||
abstractEffectModifier = new BlackMantleEffectModifier(rs);
|
||||
break;
|
||||
case BladeTrails:
|
||||
abstractEffectModifier = new BladeTrailsEffectModifier(rs);
|
||||
break;
|
||||
case Block:
|
||||
abstractEffectModifier = new BlockEffectModifier(rs);
|
||||
break;
|
||||
case BlockedPowerType:
|
||||
abstractEffectModifier = new BlockedPowerTypeEffectModifier(rs);
|
||||
break;
|
||||
case CannotAttack:
|
||||
abstractEffectModifier = new CannotAttackEffectModifier(rs);
|
||||
break;
|
||||
case CannotCast:
|
||||
abstractEffectModifier = new CannotCastEffectModifier(rs);
|
||||
break;
|
||||
case CannotMove:
|
||||
abstractEffectModifier = new CannotMoveEffectModifier(rs);
|
||||
break;
|
||||
case CannotTrack:
|
||||
abstractEffectModifier = new CannotTrackEffectModifier(rs);
|
||||
break;
|
||||
case Charmed:
|
||||
abstractEffectModifier = new CharmedEffectModifier(rs);
|
||||
break;
|
||||
case ConstrainedAmbidexterity:
|
||||
abstractEffectModifier = new ConstrainedAmbidexterityEffectModifier(rs);
|
||||
break;
|
||||
case DamageCap:
|
||||
abstractEffectModifier = new DamageCapEffectModifier(rs);
|
||||
break;
|
||||
case DamageShield:
|
||||
abstractEffectModifier = new DamageShieldEffectModifier(rs);
|
||||
break;
|
||||
case DCV:
|
||||
abstractEffectModifier = new DCVEffectModifier(rs);
|
||||
break;
|
||||
case Dodge:
|
||||
abstractEffectModifier = new DodgeEffectModifier(rs);
|
||||
break;
|
||||
case DR:
|
||||
abstractEffectModifier = new DREffectModifier(rs);
|
||||
break;
|
||||
case Durability:
|
||||
abstractEffectModifier = new DurabilityEffectModifier(rs);
|
||||
break;
|
||||
case ExclusiveDamageCap:
|
||||
abstractEffectModifier = new ExclusiveDamageCapEffectModifier(rs);
|
||||
break;
|
||||
case Fade:
|
||||
abstractEffectModifier = new FadeEffectModifier(rs);
|
||||
break;
|
||||
case Fly:
|
||||
abstractEffectModifier = new FlyEffectModifier(rs);
|
||||
break;
|
||||
case Health:
|
||||
abstractEffectModifier = new HealthEffectModifier(rs);
|
||||
break;
|
||||
case HealthFull:
|
||||
abstractEffectModifier = new HealthFullEffectModifier(rs);
|
||||
break;
|
||||
case HealthRecoverRate:
|
||||
abstractEffectModifier = new HealthRecoverRateEffectModifier(rs);
|
||||
break;
|
||||
case IgnoreDamageCap:
|
||||
abstractEffectModifier = new IgnoreDamageCapEffectModifier(rs);
|
||||
break;
|
||||
case IgnorePassiveDefense:
|
||||
abstractEffectModifier = new IgnorePassiveDefenseEffectModifier(rs);
|
||||
break;
|
||||
case ImmuneTo:
|
||||
abstractEffectModifier = new ImmuneToEffectModifier(rs);
|
||||
break;
|
||||
case ImmuneToAttack:
|
||||
abstractEffectModifier = new ImmuneToAttackEffectModifier(rs);
|
||||
break;
|
||||
case ImmuneToPowers:
|
||||
abstractEffectModifier = new ImmuneToPowersEffectModifier(rs);
|
||||
break;
|
||||
case Invisible:
|
||||
abstractEffectModifier = new InvisibleEffectModifier(rs);
|
||||
break;
|
||||
case ItemName:
|
||||
abstractEffectModifier = new ItemNameEffectModifier(rs);
|
||||
if (((ItemNameEffectModifier) abstractEffectModifier).name.isEmpty())
|
||||
break;
|
||||
if (effectBase != null)
|
||||
effectBase.setName((((ItemNameEffectModifier) abstractEffectModifier).name));
|
||||
break;
|
||||
case Mana:
|
||||
abstractEffectModifier = new ManaEffectModifier(rs);
|
||||
break;
|
||||
case ManaFull:
|
||||
abstractEffectModifier = new ManaFullEffectModifier(rs);
|
||||
break;
|
||||
case ManaRecoverRate:
|
||||
abstractEffectModifier = new ManaRecoverRateEffectModifier(rs);
|
||||
break;
|
||||
case MaxDamage:
|
||||
abstractEffectModifier = new MaxDamageEffectModifier(rs);
|
||||
break;
|
||||
case MeleeDamageModifier:
|
||||
abstractEffectModifier = new MeleeDamageEffectModifier(rs);
|
||||
break;
|
||||
case MinDamage:
|
||||
abstractEffectModifier = new MinDamageEffectModifier(rs);
|
||||
break;
|
||||
case NoMod:
|
||||
abstractEffectModifier = new NoModEffectModifier(rs);
|
||||
break;
|
||||
case OCV:
|
||||
abstractEffectModifier = new OCVEffectModifier(rs);
|
||||
break;
|
||||
case Parry:
|
||||
abstractEffectModifier = new ParryEffectModifier(rs);
|
||||
break;
|
||||
case PassiveDefense:
|
||||
abstractEffectModifier = new PassiveDefenseEffectModifier(rs);
|
||||
break;
|
||||
case PowerCost:
|
||||
abstractEffectModifier = new PowerCostEffectModifier(rs);
|
||||
break;
|
||||
case PowerCostHealth:
|
||||
abstractEffectModifier = new PowerCostHealthEffectModifier(rs);
|
||||
break;
|
||||
case PowerDamageModifier:
|
||||
abstractEffectModifier = new PowerDamageEffectModifier(rs);
|
||||
break;
|
||||
case ProtectionFrom:
|
||||
abstractEffectModifier = new ProtectionFromEffectModifier(rs);
|
||||
break;
|
||||
case Resistance:
|
||||
abstractEffectModifier = new ResistanceEffectModifier(rs);
|
||||
break;
|
||||
case ScaleHeight:
|
||||
abstractEffectModifier = new ScaleHeightEffectModifier(rs);
|
||||
break;
|
||||
case ScaleWidth:
|
||||
abstractEffectModifier = new ScaleWidthEffectModifier(rs);
|
||||
break;
|
||||
case ScanRange:
|
||||
abstractEffectModifier = new ScanRangeEffectModifier(rs);
|
||||
break;
|
||||
case SeeInvisible:
|
||||
abstractEffectModifier = new SeeInvisibleEffectModifier(rs);
|
||||
break;
|
||||
case Silenced:
|
||||
abstractEffectModifier = new SilencedEffectModifier(rs);
|
||||
break;
|
||||
case Skill:
|
||||
abstractEffectModifier = new SkillEffectModifier(rs);
|
||||
break;
|
||||
case Slay:
|
||||
abstractEffectModifier = new SlayEffectModifier(rs);
|
||||
break;
|
||||
case Speed:
|
||||
abstractEffectModifier = new SpeedEffectModifier(rs);
|
||||
break;
|
||||
case SpireBlock:
|
||||
abstractEffectModifier = new SpireBlockEffectModifier(rs);
|
||||
break;
|
||||
case Stamina:
|
||||
abstractEffectModifier = new StaminaEffectModifier(rs);
|
||||
break;
|
||||
case StaminaFull:
|
||||
abstractEffectModifier = new StaminaFullEffectModifier(rs);
|
||||
break;
|
||||
case StaminaRecoverRate:
|
||||
abstractEffectModifier = new StaminaRecoverRateEffectModifier(rs);
|
||||
break;
|
||||
case Stunned:
|
||||
abstractEffectModifier = new StunnedEffectModifier(rs);
|
||||
break;
|
||||
case Value:
|
||||
abstractEffectModifier = new ValueEffectModifier(rs);
|
||||
if (effectBase != null) {
|
||||
ValueEffectModifier valueEffect = (ValueEffectModifier) abstractEffectModifier;
|
||||
effectBase.setValue(valueEffect.minMod);
|
||||
}
|
||||
break;
|
||||
case WeaponProc:
|
||||
abstractEffectModifier = new WeaponProcEffectModifier(rs);
|
||||
break;
|
||||
case WeaponRange:
|
||||
abstractEffectModifier = new WeaponRangeEffectModifier(rs);
|
||||
break;
|
||||
case WeaponSpeed:
|
||||
abstractEffectModifier = new WeaponSpeedEffectModifier(rs);
|
||||
break;
|
||||
|
||||
}
|
||||
return abstractEffectModifier;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.EffectsResourceCosts;
|
||||
import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class dbEffectsResourceCostHandler extends dbHandlerBase {
|
||||
|
||||
public dbEffectsResourceCostHandler() {
|
||||
this.localClass = EffectsResourceCosts.class;
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public void LOAD_ALL_COSTMAPS() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_effect_costmaps`")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
String effectID = rs.getString("effectID");
|
||||
String costString = rs.getString("costmap");
|
||||
JSONObject costJSON = new JSONObject(costString);
|
||||
HashMap<mbEnums.ResourceType, Integer> costmap = new HashMap<>();
|
||||
|
||||
for (String key : costJSON.keySet()) {
|
||||
int value = costJSON.getInt(key);
|
||||
costmap.put(mbEnums.ResourceType.valueOf(key), value);
|
||||
}
|
||||
|
||||
PowersManager._effect_costMaps.put(effectID, costmap);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -95,6 +95,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean ADD_TO_BANISHED_FROM_GUILDLIST(int target, long characterID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, target))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guild_banishlist` (`GuildID`, `CharacterID`) VALUES (?,?)")) {
|
||||
|
||||
@@ -111,6 +114,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean REMOVE_FROM_BANISH_LIST(int target, long characterID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, target))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guild_banishlist` (`GuildID`, `CharacterID`) VALUES (?,?)")) {
|
||||
|
||||
@@ -358,6 +364,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean SET_GUILD_OWNED_CITY(int guildID, int cityID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, guildID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_guild` SET `ownedCity`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -374,6 +383,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean SET_GUILD_LEADER(int objectUUID, int guildID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, guildID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_guild` SET `leaderUID`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -413,6 +425,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
Guild guild = null;
|
||||
GuildTag guildTag = g.getGuildTag();
|
||||
|
||||
if (DbManager.refuseStaticWrite(g))
|
||||
return null;
|
||||
|
||||
if (guildTag == null)
|
||||
return null;
|
||||
|
||||
@@ -465,6 +480,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_PARENT(int guildUID, int parentUID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, guildUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `object` SET `parent`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -483,20 +501,19 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
int row_count = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `object` WHERE `UID` = ?")) {
|
||||
if (DbManager.refuseStaticWrite(guild))
|
||||
return 0;
|
||||
|
||||
preparedStatement.setLong(1, guild.getObjectUUID());
|
||||
row_count = preparedStatement.executeUpdate();
|
||||
row_count = Math.max(deleteObjectTree(guild.getObjectUUID(), null), 0);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return row_count;
|
||||
}
|
||||
|
||||
public boolean UPDATE_MINETIME(int guildUID, int mineTime) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, guildUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_guild` SET `mineTime`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -564,6 +581,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateDatabase(final Guild g) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(g))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_guild` SET `name`=?, `backgroundColor01`=?, `backgroundColor02`=?, `symbolColor`=?, `backgroundDesign`=?, `symbol`=?, `charter`=?, `motd`=?, `icMotd`=?, `nationMotd`=?, `leaderUID`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -590,6 +610,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean ADD_TO_ALLIANCE_LIST(final long sourceGuildID, final long targetGuildID, boolean isRecommended, boolean isAlly, String recommender) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, sourceGuildID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guild_allianceenemylist` (`GuildID`, `OtherGuildID`,`isRecommended`, `isAlliance`, `recommender`) VALUES (?,?,?,?,?)")) {
|
||||
|
||||
@@ -609,6 +632,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean REMOVE_FROM_ALLIANCE_LIST(final long sourceGuildID, long targetGuildID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, sourceGuildID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guild_allianceenemylist` WHERE `GuildID`=? AND `OtherGuildID`=?")) {
|
||||
|
||||
@@ -625,6 +651,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_RECOMMENDED(final long sourceGuildID, long targetGuildID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, sourceGuildID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_guild_allianceenemylist` SET `isRecommended` = ? WHERE `GuildID`=? AND `OtherGuildID`=?")) {
|
||||
|
||||
@@ -641,6 +670,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_ALLIANCE(final long sourceGuildID, long targetGuildID, boolean isAlly) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, sourceGuildID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_guild_allianceenemylist` SET `isAlliance` = ? WHERE `GuildID`=? AND `OtherGuildID`=?")) {
|
||||
|
||||
@@ -657,6 +689,9 @@ public class dbGuildHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_ALLIANCE_AND_RECOMMENDED(final long sourceGuildID, long targetGuildID, boolean isAlly) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Guild, sourceGuildID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_guild_allianceenemylist` SET `isRecommended` = ?, `isAlliance` = ? WHERE `GuildID`=? AND `OtherGuildID`=?")) {
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@ import engine.objects.AbstractGameObject;
|
||||
import engine.objects.AbstractWorldObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class dbHandlerBase {
|
||||
@@ -77,4 +80,51 @@ public abstract class dbHandlerBase {
|
||||
}
|
||||
return objectList;
|
||||
}
|
||||
|
||||
// Deletes an object row and every row below it by object.parent, as the dropped ref_parent cascade did
|
||||
// (World Boot Plan 2.4). typeFilter limits the root row to one object type; null deletes any type.
|
||||
// Returns the number of root rows deleted.
|
||||
|
||||
protected int deleteObjectTree(long objectUID, String typeFilter) {
|
||||
|
||||
String descendantSql = "DELETE FROM `object` WHERE `UID` IN (SELECT `UID` FROM (WITH RECURSIVE `tree` AS "
|
||||
+ "(SELECT `UID` FROM `object` WHERE `parent` = ? UNION ALL "
|
||||
+ "SELECT `object`.`UID` FROM `object` INNER JOIN `tree` ON `object`.`parent` = `tree`.`UID`) "
|
||||
+ "SELECT `UID` FROM `tree`) AS `descendants`)";
|
||||
String rootSql = typeFilter == null ? "DELETE FROM `object` WHERE `UID` = ?"
|
||||
: "DELETE FROM `object` WHERE `UID` = ? AND `type` = ?";
|
||||
int rootCount = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection()) {
|
||||
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
try (PreparedStatement descendantStatement = connection.prepareStatement(descendantSql);
|
||||
PreparedStatement rootStatement = connection.prepareStatement(rootSql)) {
|
||||
|
||||
descendantStatement.setLong(1, objectUID);
|
||||
descendantStatement.executeUpdate();
|
||||
|
||||
rootStatement.setLong(1, objectUID);
|
||||
|
||||
if (typeFilter != null)
|
||||
rootStatement.setString(2, typeFilter);
|
||||
|
||||
rootCount = rootStatement.executeUpdate();
|
||||
connection.commit();
|
||||
|
||||
} catch (SQLException e) {
|
||||
connection.rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rootCount;
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@ import engine.mbEnums.ItemType;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.CharacterItemManager;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -177,47 +175,23 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
return itemList;
|
||||
}
|
||||
|
||||
public void LOAD_ITEM_TEMPLATES() {
|
||||
public HashMap<Integer, Integer> LOAD_TEMPLATE_MODTABLES() {
|
||||
|
||||
HashMap<ItemType, Integer> templateTCountMap = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_templates`;");
|
||||
ResultSet rs = preparedStatement.executeQuery()) {
|
||||
|
||||
while (rs.next()) {
|
||||
int templateID = rs.getInt("id");
|
||||
JSONObject jsonObject = new JSONObject(rs.getString("template"));
|
||||
ItemTemplate itemTemplate = new ItemTemplate(jsonObject);
|
||||
itemTemplate.template_id = templateID;
|
||||
ItemTemplate.templates.put(templateID, itemTemplate);
|
||||
|
||||
templateTCountMap.merge(itemTemplate.item_type, 1, Integer::sum);
|
||||
}
|
||||
|
||||
Logger.info(templateTCountMap.toString());
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void LOAD_TEMPLATE_MODTABLES() {
|
||||
HashMap<Integer, Integer> modTables = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_vendor_items`;");
|
||||
ResultSet rs = preparedStatement.executeQuery()) {
|
||||
|
||||
while (rs.next()) {
|
||||
int templateID = rs.getInt("templateID");
|
||||
int modTable = rs.getInt("modTable");
|
||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
||||
template.modTable = modTable;
|
||||
}
|
||||
while (rs.next())
|
||||
modTables.put(rs.getInt("templateID"), rs.getInt("modTable"));
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("read: " + modTables.size());
|
||||
return modTables;
|
||||
}
|
||||
|
||||
public Item GET_ITEM(final int itemUUID) {
|
||||
@@ -325,7 +299,7 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
|
||||
for (Item item : inventory) {
|
||||
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
continue;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
@@ -474,7 +448,7 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
*/
|
||||
public boolean UPDATE_GOLD(final Item item, int newValue, int oldValue) {
|
||||
|
||||
if (!item.template.item_type.equals(ItemType.GOLD))
|
||||
if (!item.template.getItemType().equals(ItemType.GOLD))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
@@ -554,7 +528,7 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
|
||||
// Write 0 if we will not modify the value from template
|
||||
|
||||
if (value == item.template.item_value)
|
||||
if (value == item.template.getItemValue())
|
||||
value = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.Kit;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class dbKitHandler extends dbHandlerBase {
|
||||
|
||||
public dbKitHandler() {
|
||||
this.localClass = Kit.class;
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public ArrayList<Kit> GET_ALL_KITS() {
|
||||
|
||||
ArrayList<Kit> kitList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_validkit`")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
kitList = getObjectsFromRs(rs, 20);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return kitList;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.loot.*;
|
||||
import engine.objects.Item;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -221,20 +220,4 @@ public class dbLootHandler extends dbHandlerBase {
|
||||
return bootySets;
|
||||
}
|
||||
|
||||
public void LOAD_ENCHANT_VALUES() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `IDString`, `minMod` FROM `static_power_effectmod` WHERE `modType` = ?")) {
|
||||
|
||||
preparedStatement.setString(1, "Value");
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
Item.addEnchantValue(rs.getString("IDString"), rs.getInt("minMod"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,8 +13,6 @@ import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.MobBase;
|
||||
import engine.objects.MobBaseEffects;
|
||||
import engine.objects.MobBaseStats;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -69,71 +67,10 @@ public class dbMobBaseHandler extends dbHandlerBase {
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + mobbaseList.size() + " mobbases");
|
||||
|
||||
return mobbaseList;
|
||||
}
|
||||
|
||||
public ArrayList<MobBaseEffects> GET_RUNEBASE_EFFECTS(int runeID) {
|
||||
|
||||
ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_effects` WHERE `mobbaseUUID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, runeID);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
MobBaseEffects mbs = new MobBaseEffects(rs);
|
||||
effectsList.add(mbs);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return effectsList;
|
||||
}
|
||||
|
||||
public MobBaseStats LOAD_STATS(int mobBaseUUID) {
|
||||
|
||||
MobBaseStats mobBaseStats = MobBaseStats.GetGenericStats();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_stats` WHERE `mobbaseUUID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, mobBaseUUID);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
mobBaseStats = new MobBaseStats(rs);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return mobBaseStats;
|
||||
}
|
||||
|
||||
public void LOAD_ALL_MOBBASE_SPEEDS(MobBase mobBase) {
|
||||
|
||||
if (mobBase.getLoadID() == 0)
|
||||
return;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_race` WHERE `mobbaseID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, mobBase.getLoadID());
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
float walk = rs.getFloat("walkStandard");
|
||||
float walkCombat = rs.getFloat("walkCombat");
|
||||
float run = rs.getFloat("runStandard");
|
||||
float runCombat = rs.getFloat("runCombat");
|
||||
mobBase.updateSpeeds(walk, walkCombat, run, runCombat);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,9 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
|
||||
Mob mobile = null;
|
||||
|
||||
if (DbManager.refuseStaticWrite(toAdd))
|
||||
return null;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
|
||||
|
||||
@@ -84,6 +87,9 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mob))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_mob SET upgradeDate=? "
|
||||
+ "WHERE UID = ?")) {
|
||||
@@ -106,16 +112,12 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
public int DELETE_MOB(final Mob mob) {
|
||||
|
||||
int row_count = 0;
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `object` WHERE `UID` = ?")) {
|
||||
|
||||
preparedStatement.setLong(1, mob.getDBID());
|
||||
row_count = preparedStatement.executeUpdate();
|
||||
if (DbManager.refuseStaticWrite(mob))
|
||||
return 0;
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
row_count = Math.max(deleteObjectTree(mob.getDBID(), null), 0);
|
||||
|
||||
}
|
||||
return row_count;
|
||||
}
|
||||
|
||||
@@ -146,6 +148,9 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
|
||||
public boolean ADD_GUARD_MINION(final long captainUID, final String minionName) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Mob, captainUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guards` (`captainUID`, `minionName`) VALUES (?,?)")) {
|
||||
|
||||
@@ -162,6 +167,9 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
|
||||
public boolean REMOVE_GUARD_MINION(final long captainUID, final String minionName) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Mob, captainUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `minionName`=? LIMIT 1;")) {
|
||||
|
||||
@@ -178,6 +186,9 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
|
||||
public boolean REMOVE_ALL_MINIONS(final long captainUID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Mob, captainUID))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=?;")) {
|
||||
|
||||
@@ -212,6 +223,9 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
|
||||
int row_count = 0;
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.Mob, mobID))
|
||||
return 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `object` INNER JOIN `obj_mob` On `object`.`UID` = `obj_mob`.`UID` SET `object`.`parent`=?, `obj_mob`.`mob_spawnX`=?, `obj_mob`.`mob_spawnY`=?, `obj_mob`.`mob_spawnZ`=? WHERE `obj_mob`.`UID`=?;")) {
|
||||
|
||||
@@ -234,6 +248,9 @@ public class dbMobHandler extends dbHandlerBase {
|
||||
|
||||
String result = "";
|
||||
|
||||
if (DbManager.refuseStaticWrite(m))
|
||||
return result;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("CALL mob_SETPROP(?,?,?)")) {
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
runeSets.put(runeSetID, runeList);
|
||||
} else {
|
||||
ArrayList<Integer> runeList = runeSets.get(runeSetID);
|
||||
runeList.add(runeSetID);
|
||||
runeList.add(runeBaseID);
|
||||
runeSets.put(runeSetID, runeList);
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
NPC npc = null;
|
||||
|
||||
if (DbManager.refuseStaticWrite(toAdd))
|
||||
return null;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("CALL `npc_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
|
||||
|
||||
@@ -120,16 +123,11 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
npc.removeFromZone();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `object` WHERE `UID` = ?")) {
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return 0;
|
||||
|
||||
preparedStatement.setLong(1, npc.getDBID());
|
||||
row_count = preparedStatement.executeUpdate();
|
||||
row_count = Math.max(deleteObjectTree(npc.getDBID(), null), 0);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
|
||||
}
|
||||
return row_count;
|
||||
}
|
||||
|
||||
@@ -172,6 +170,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
int rowCount;
|
||||
|
||||
if (DbManager.refuseStaticWrite(mbEnums.GameObjectType.NPC, npcID))
|
||||
return 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `object` INNER JOIN `obj_npc` On `object`.`UID` = `obj_npc`.`UID` SET `object`.`parent`=?, `obj_npc`.`npc_spawnX`=?, `obj_npc`.`npc_spawnY`=?, `obj_npc`.`npc_spawnZ`=? WHERE `obj_npc`.`UID`=?;")) {
|
||||
|
||||
@@ -195,6 +196,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
String result = "";
|
||||
|
||||
if (DbManager.refuseStaticWrite(n))
|
||||
return result;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("CALL npc_SETPROP(?,?,?)")) {
|
||||
|
||||
@@ -215,6 +219,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public void updateDatabase(final NPC npc) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_npc SET npc_name=?, npc_contractID=?, npc_typeID=?, npc_guildID=?,"
|
||||
+ " npc_spawnX=?, npc_spawnY=?, npc_spawnZ=?, npc_level=? ,"
|
||||
@@ -242,6 +249,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public boolean updateUpgradeTime(NPC npc, DateTime upgradeDateTime) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_npc SET upgradeDate=? "
|
||||
+ "WHERE UID = ?")) {
|
||||
@@ -264,6 +274,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_MOBBASE(NPC npc, int mobBaseID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_npc` SET `npc_raceID`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -280,6 +293,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_EQUIPSET(NPC npc, int equipSetID) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_npc` SET `equipsetID`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -296,6 +312,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_NAME(NPC npc, String name) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_npc` SET `npc_name`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -312,6 +331,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_RACE(NPC npc, int value) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_npc` SET `npc_raceID`=? WHERE `UID`=?")) {
|
||||
|
||||
@@ -363,6 +385,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public boolean UPDATE_PROFITS(NPC npc, ProfitType profitType, float value) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_npc_profits` SET `" + profitType.dbField + "` = ? WHERE `npcUID`=?")) {
|
||||
|
||||
@@ -398,6 +423,9 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
|
||||
public boolean CREATE_PROFITS(NPC npc) {
|
||||
|
||||
if (DbManager.refuseStaticWrite(npc))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_npc_profits` (`npcUID`) VALUES (?)")) {
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.Mob;
|
||||
import engine.powers.EffectsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class dbPowerHandler extends dbHandlerBase {
|
||||
|
||||
public dbPowerHandler() {
|
||||
this.localClass = Mob.class;
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public static void addAllSourceTypes() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_sourcetype")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
String IDString, source;
|
||||
|
||||
while (rs.next()) {
|
||||
IDString = rs.getString("IDString");
|
||||
int token = DbManager.hasher.SBStringHash(IDString);
|
||||
|
||||
source = rs.getString("source").replace("-", "").trim();
|
||||
mbEnums.EffectSourceType effectSourceType = mbEnums.EffectSourceType.GetEffectSourceType(source);
|
||||
|
||||
if (EffectsBase.effectSourceTypeMap.containsKey(token) == false)
|
||||
EffectsBase.effectSourceTypeMap.put(token, new HashSet<>());
|
||||
|
||||
EffectsBase.effectSourceTypeMap.get(token).add(effectSourceType);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addAllAnimationOverrides() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_animation_override")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
String IDString;
|
||||
int animation;
|
||||
while (rs.next()) {
|
||||
IDString = rs.getString("IDString");
|
||||
|
||||
EffectsBase eb = PowersManager.getEffectByIDString(IDString);
|
||||
if (eb != null)
|
||||
IDString = eb.getIDString();
|
||||
|
||||
animation = rs.getInt("animation");
|
||||
PowersManager.AnimationOverrides.put(IDString, animation);
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,30 +27,17 @@ public class dbPromotionClassHandler extends dbHandlerBase {
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public ArrayList<Integer> GET_ALLOWED_RUNES(final PromotionClass pc) {
|
||||
|
||||
ArrayList<Integer> runeList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotionrunereq` WHERE `promoID`=?")) {
|
||||
|
||||
preparedStatement.setInt(1, pc.getObjectUUID());
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
runeList.add(rs.getInt("runereqID"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
|
||||
}
|
||||
return runeList;
|
||||
}
|
||||
|
||||
public PromotionClass GET_PROMOTION_CLASS(final int objectUUID) {
|
||||
|
||||
PromotionClass promotionClass = null;
|
||||
PromotionClass promotionClass;
|
||||
|
||||
if (objectUUID == 0)
|
||||
return null;
|
||||
|
||||
promotionClass = (PromotionClass) DbManager.getFromCache(mbEnums.GameObjectType.PromotionClass, objectUUID);
|
||||
|
||||
if (promotionClass != null)
|
||||
return promotionClass;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?")) {
|
||||
|
||||
@@ -10,15 +10,14 @@
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.objects.Race;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class dbRaceHandler extends dbHandlerBase {
|
||||
|
||||
@@ -46,27 +45,6 @@ public class dbRaceHandler extends dbHandlerBase {
|
||||
return integerSet;
|
||||
}
|
||||
|
||||
public HashSet<Integer> BEARD_STYLES_FOR_RACE(final int id) {
|
||||
|
||||
HashSet<Integer> integerSet = new HashSet<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `beardStyle` FROM `static_rune_racebeardstyle` WHERE `RaceID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, id);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
integerSet.add(rs.getInt(1));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return integerSet;
|
||||
}
|
||||
|
||||
public HashSet<Integer> HAIR_COLORS_FOR_RACE(final int id) {
|
||||
|
||||
HashSet<Integer> integerSet = new HashSet<>();
|
||||
@@ -89,28 +67,6 @@ public class dbRaceHandler extends dbHandlerBase {
|
||||
|
||||
}
|
||||
|
||||
public HashSet<Integer> HAIR_STYLES_FOR_RACE(final int id) {
|
||||
|
||||
HashSet<Integer> integerSet = new HashSet<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `hairStyle` FROM `static_rune_racehairstyle` WHERE `RaceID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, id);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
integerSet.add(rs.getInt(1));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return integerSet;
|
||||
|
||||
}
|
||||
|
||||
public HashSet<Integer> SKIN_COLOR_FOR_RACE(final int id) {
|
||||
|
||||
HashSet<Integer> integerSet = new HashSet<>();
|
||||
@@ -132,32 +88,23 @@ public class dbRaceHandler extends dbHandlerBase {
|
||||
return integerSet;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Race> LOAD_ALL_RACES() {
|
||||
// Rune id -> {minHeight, strHeightMod}; the rows also decide which race runes are player races
|
||||
public HashMap<Integer, float[]> LOAD_RACE_HEIGHTS() {
|
||||
|
||||
ConcurrentHashMap<Integer, Race> races;
|
||||
Race thisRace;
|
||||
|
||||
races = new ConcurrentHashMap<>();
|
||||
int recordsRead = 0;
|
||||
HashMap<Integer, float[]> raceHeights = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_race")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
recordsRead++;
|
||||
thisRace = new Race(rs);
|
||||
|
||||
races.put(thisRace.getRaceRuneID(), thisRace);
|
||||
}
|
||||
while (rs.next())
|
||||
raceHeights.put(rs.getInt("ID"), new float[]{rs.getFloat("minHeight"), rs.getFloat("strHeightMod")});
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + races.size());
|
||||
return races;
|
||||
return raceHeights;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.objects.Resists;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class dbResistHandler extends dbHandlerBase {
|
||||
|
||||
public dbResistHandler() {
|
||||
|
||||
}
|
||||
|
||||
public Resists GET_RESISTS_FOR_MOB(int resistID) {
|
||||
|
||||
Resists resists = null;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mob_resists` WHERE `ID` = ?;")) {
|
||||
|
||||
preparedStatement.setInt(1, resistID);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
if (rs.next())
|
||||
resists = new Resists(rs);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return resists;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.RuneBaseAttribute;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class dbRuneBaseAttributeHandler extends dbHandlerBase {
|
||||
|
||||
public dbRuneBaseAttributeHandler() {
|
||||
this.localClass = RuneBaseAttribute.class;
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseAttribute> GET_ATTRIBUTES_FOR_RUNEBASE() {
|
||||
|
||||
ArrayList<RuneBaseAttribute> runeBaseAttributesList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runebaseattribute`")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
runeBaseAttributesList = getObjectsFromRs(rs, 10);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return runeBaseAttributesList;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.RuneBaseEffect;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class dbRuneBaseEffectHandler extends dbHandlerBase {
|
||||
|
||||
public dbRuneBaseEffectHandler() {
|
||||
this.localClass = RuneBaseEffect.class;
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> GET_EFFECTS_FOR_RUNEBASE(int id) {
|
||||
|
||||
ArrayList<RuneBaseEffect> runeBaseEffectsList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_baseeffect` WHERE `runeID`=?")) {
|
||||
|
||||
preparedStatement.setInt(1, id);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
runeBaseEffectsList = getObjectsFromRs(rs, 250);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return runeBaseEffectsList;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> GET_ALL_RUNEBASE_EFFECTS() {
|
||||
|
||||
ArrayList<RuneBaseEffect> runeBaseEffectsList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_baseeffect`;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
runeBaseEffectsList = getObjectsFromRs(rs, 250);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return runeBaseEffectsList;
|
||||
}
|
||||
|
||||
//This calls from cache only. Call this AFTER caching all runebase effects;
|
||||
|
||||
public HashMap<Integer, ArrayList<RuneBaseEffect>> LOAD_BASEEFFECTS_FOR_RUNEBASE() {
|
||||
|
||||
HashMap<Integer, ArrayList<RuneBaseEffect>> runeBaseEffectSet;
|
||||
runeBaseEffectSet = new HashMap<>();
|
||||
|
||||
for (AbstractGameObject runeBaseEffect : DbManager.getList(GameObjectType.RuneBaseEffect)) {
|
||||
|
||||
int runeBaseID = ((RuneBaseEffect) runeBaseEffect).getRuneBaseID();
|
||||
if (runeBaseEffectSet.get(runeBaseID) == null) {
|
||||
ArrayList<RuneBaseEffect> runeBaseEffectList = new ArrayList<>();
|
||||
runeBaseEffectList.add((RuneBaseEffect) runeBaseEffect);
|
||||
runeBaseEffectSet.put(runeBaseID, runeBaseEffectList);
|
||||
} else {
|
||||
ArrayList<RuneBaseEffect> runeBaseEffectList = runeBaseEffectSet.get(runeBaseID);
|
||||
runeBaseEffectList.add((RuneBaseEffect) runeBaseEffect);
|
||||
runeBaseEffectSet.put(runeBaseID, runeBaseEffectList);
|
||||
}
|
||||
}
|
||||
return runeBaseEffectSet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,17 +11,16 @@ package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.BaseClass;
|
||||
import engine.objects.PromotionClass;
|
||||
import engine.objects.Race;
|
||||
import engine.objects.RuneBase;
|
||||
import engine.powers.RunePowerEntry;
|
||||
import engine.powers.RuneSkillAdjustEntry;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class dbRuneBaseHandler extends dbHandlerBase {
|
||||
|
||||
@@ -30,231 +29,57 @@ public class dbRuneBaseHandler extends dbHandlerBase {
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public static HashMap<Integer, ArrayList<RunePowerEntry>> LOAD_RUNE_POWERS() {
|
||||
// static_rune_lookup is generated for the DB views; a failed write must never stop the boot
|
||||
public static void WRITE_RUNE_LOOKUP() {
|
||||
|
||||
HashMap<Integer, ArrayList<RunePowerEntry>> mobPowers = new HashMap<>();
|
||||
RunePowerEntry runePowerEntry;
|
||||
|
||||
int rune_id;
|
||||
int recordsRead = 0;
|
||||
int rowsWritten = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_powers")) {
|
||||
PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM `static_rune_lookup`");
|
||||
PreparedStatement insertStatement = connection.prepareStatement("INSERT INTO `static_rune_lookup` (`ID`, `type`, `name`) VALUES (?, ?, ?)")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
while (rs.next()) {
|
||||
try {
|
||||
deleteStatement.executeUpdate();
|
||||
|
||||
recordsRead++;
|
||||
|
||||
rune_id = rs.getInt("rune_id");
|
||||
runePowerEntry = new RunePowerEntry(rs);
|
||||
|
||||
if (mobPowers.get(rune_id) == null) {
|
||||
ArrayList<RunePowerEntry> runePowerList = new ArrayList<>();
|
||||
runePowerList.add(runePowerEntry);
|
||||
mobPowers.put(rune_id, runePowerList);
|
||||
} else {
|
||||
ArrayList<RunePowerEntry> powerList = mobPowers.get(rune_id);
|
||||
powerList.add(runePowerEntry);
|
||||
mobPowers.put(rune_id, powerList);
|
||||
for (Race race : Race.getAllRaces()) {
|
||||
addRuneLookupRow(insertStatement, race.getRaceRuneID(), "RACE", race.getName());
|
||||
rowsWritten++;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return mobPowers;
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
|
||||
return mobPowers;
|
||||
}
|
||||
|
||||
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> LOAD_RUNE_SKILL_ADJUSTS() {
|
||||
|
||||
HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> runeSkillAdjusts = new HashMap<>();
|
||||
RuneSkillAdjustEntry runeSkillAdjustEntry;
|
||||
|
||||
int rune_id;
|
||||
int recordsRead = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_skill_adjusts")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
recordsRead++;
|
||||
|
||||
rune_id = rs.getInt("rune_id");
|
||||
runeSkillAdjustEntry = new RuneSkillAdjustEntry(rs);
|
||||
|
||||
if (runeSkillAdjusts.get(rune_id) == null) {
|
||||
ArrayList<RuneSkillAdjustEntry> skillAdjustList = new ArrayList<>();
|
||||
skillAdjustList.add(runeSkillAdjustEntry);
|
||||
runeSkillAdjusts.put(rune_id, skillAdjustList);
|
||||
} else {
|
||||
ArrayList<RuneSkillAdjustEntry> powerList = runeSkillAdjusts.get(rune_id);
|
||||
powerList.add(runeSkillAdjustEntry);
|
||||
runeSkillAdjusts.put(rune_id, powerList);
|
||||
for (AbstractGameObject baseClass : DbManager.getMap(mbEnums.GameObjectType.BaseClass).values()) {
|
||||
addRuneLookupRow(insertStatement, baseClass.getObjectUUID(), "BASECLASS", ((BaseClass) baseClass).getName());
|
||||
rowsWritten++;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return runeSkillAdjusts;
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + runeSkillAdjusts.size());
|
||||
return runeSkillAdjusts;
|
||||
}
|
||||
|
||||
public void GET_RUNE_REQS(final RuneBase rb) {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runereq` WHERE `runeID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, rb.getObjectUUID());
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
int type = rs.getInt("type");
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
rb.getRace().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
|
||||
break;
|
||||
case 2:
|
||||
rb.getBaseClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
|
||||
break;
|
||||
case 3:
|
||||
rb.getPromotionClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
|
||||
break;
|
||||
case 4:
|
||||
rb.getDiscipline().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
|
||||
break;
|
||||
case 5:
|
||||
rb.getOverwrite().add(rs.getInt("requiredRuneID"));
|
||||
break;
|
||||
case 6:
|
||||
rb.setLevelRequired(rs.getInt("requiredRuneID"));
|
||||
break;
|
||||
for (AbstractGameObject promotionClass : DbManager.getMap(mbEnums.GameObjectType.PromotionClass).values()) {
|
||||
addRuneLookupRow(insertStatement, promotionClass.getObjectUUID(), "PROMOTION", ((PromotionClass) promotionClass).getName());
|
||||
rowsWritten++;
|
||||
}
|
||||
|
||||
insertStatement.executeBatch();
|
||||
connection.commit();
|
||||
} catch (SQLException | RuntimeException e) {
|
||||
// Roll back before setAutoCommit(true), which would otherwise commit the delete
|
||||
connection.rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
} catch (Exception e) {
|
||||
Logger.warn("static_rune_lookup not written; DB views keep their old names: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.info("static_rune_lookup: wrote " + rowsWritten + " rows");
|
||||
}
|
||||
|
||||
public RuneBase GET_RUNEBASE(final int id) {
|
||||
|
||||
RuneBase runeBase = null;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runebase` WHERE `ID` = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, id);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
runeBase = (RuneBase) getObjectFromRs(rs);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return runeBase;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBase> LOAD_ALL_RUNEBASES() {
|
||||
|
||||
ArrayList<RuneBase> runeBasesList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runebase`;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
runeBasesList = getObjectsFromRs(rs, 1000);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return runeBasesList;
|
||||
}
|
||||
|
||||
public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS() {
|
||||
|
||||
HashMap<Integer, ArrayList<Integer>> runeSets = new HashMap<>();
|
||||
|
||||
int recordsRead = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_baseclassrune")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
recordsRead++;
|
||||
|
||||
int baseClassID = rs.getInt("BaseClassesID");
|
||||
int runeBaseID = rs.getInt("RuneBaseID");
|
||||
|
||||
if (runeSets.get(baseClassID) == null) {
|
||||
ArrayList<Integer> runeList = new ArrayList<>();
|
||||
runeList.add(runeBaseID);
|
||||
runeSets.put(baseClassID, runeList);
|
||||
} else {
|
||||
ArrayList<Integer> runeList = runeSets.get(baseClassID);
|
||||
runeList.add(runeBaseID);
|
||||
runeSets.put(baseClassID, runeList);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + runeSets.size());
|
||||
|
||||
return runeSets;
|
||||
}
|
||||
|
||||
public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_RACE() {
|
||||
|
||||
HashMap<Integer, ArrayList<Integer>> runeSets;
|
||||
|
||||
runeSets = new HashMap<>();
|
||||
int recordsRead = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_racerune")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
recordsRead++;
|
||||
|
||||
int raceID = rs.getInt("RaceID");
|
||||
int runeBaseID = rs.getInt("RuneBaseID");
|
||||
|
||||
if (runeSets.get(raceID) == null) {
|
||||
ArrayList<Integer> runeList = new ArrayList<>();
|
||||
runeList.add(runeBaseID);
|
||||
runeSets.put(raceID, runeList);
|
||||
} else {
|
||||
ArrayList<Integer> runeList = runeSets.get(raceID);
|
||||
runeList.add(runeBaseID);
|
||||
runeSets.put(raceID, runeList);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + runeSets.size());
|
||||
return runeSets;
|
||||
private static void addRuneLookupRow(PreparedStatement insertStatement, int runeID, String type, String name) throws SQLException {
|
||||
insertStatement.setInt(1, runeID);
|
||||
insertStatement.setString(2, type);
|
||||
insertStatement.setString(3, name);
|
||||
insertStatement.addBatch();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ package engine.db.handlers;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.MaxSkills;
|
||||
import engine.objects.SkillsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -20,7 +19,6 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class dbSkillBaseHandler extends dbHandlerBase {
|
||||
@@ -31,122 +29,33 @@ public class dbSkillBaseHandler extends dbHandlerBase {
|
||||
}
|
||||
|
||||
public SkillsBase GET_BASE(final int objectUUID) {
|
||||
|
||||
SkillsBase skillsBase = (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID);
|
||||
|
||||
if (skillsBase != null)
|
||||
return skillsBase;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE ID = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, objectUUID);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
skillsBase = (SkillsBase) getObjectFromRs(rs);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
SkillsBase.putInCache(skillsBase);
|
||||
return skillsBase;
|
||||
return (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID);
|
||||
}
|
||||
|
||||
public SkillsBase GET_BASE_BY_NAME(String name) {
|
||||
|
||||
SkillsBase skillsBase = SkillsBase.getFromCache(name);
|
||||
|
||||
if (skillsBase != null)
|
||||
return skillsBase;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE name = ?")) {
|
||||
|
||||
preparedStatement.setString(1, name);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
skillsBase = (SkillsBase) getObjectFromRs(rs);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
SkillsBase.putInCache(skillsBase);
|
||||
return skillsBase;
|
||||
return SkillsBase.getFromCache(name);
|
||||
}
|
||||
|
||||
public SkillsBase GET_BASE_BY_TOKEN(final int token) {
|
||||
return SkillsBase.getFromCache(token);
|
||||
}
|
||||
|
||||
SkillsBase skillsBase = SkillsBase.getFromCache(token);
|
||||
public HashMap<Integer, String> GET_ALL_SKILL_NAMES() {
|
||||
|
||||
if (skillsBase != null)
|
||||
return skillsBase;
|
||||
HashMap<Integer, String> skillNames = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE token = ?")) {
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT ID, name FROM static_skill_skillsbase")) {
|
||||
|
||||
preparedStatement.setInt(1, token);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
skillsBase = (SkillsBase) getObjectFromRs(rs);
|
||||
while (rs.next())
|
||||
skillNames.put(rs.getInt("ID"), rs.getString("name"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
SkillsBase.putInCache(skillsBase);
|
||||
return skillsBase;
|
||||
return skillNames;
|
||||
}
|
||||
|
||||
public void LOAD_ALL_MAX_SKILLS_FOR_CONTRACT() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_maxskills`")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
MaxSkills maxSKills = new MaxSkills(rs);
|
||||
|
||||
if (MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()) == null) {
|
||||
ArrayList<MaxSkills> newMaxSkillsList = new ArrayList<>();
|
||||
newMaxSkillsList.add(maxSKills);
|
||||
MaxSkills.MaxSkillsSet.put(maxSKills.getRuneID(), newMaxSkillsList);
|
||||
} else
|
||||
MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()).add(maxSKills);
|
||||
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void LOAD_ALL_RUNE_SKILLS() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_skill_skillsgranted`")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
int runeID = rs.getInt("runeID");
|
||||
int token = rs.getInt("token");
|
||||
int amount = rs.getInt("amount");
|
||||
|
||||
if (SkillsBase.runeSkillsCache.get(runeID) == null)
|
||||
SkillsBase.runeSkillsCache.put(runeID, new HashMap<>());
|
||||
|
||||
SkillsBase.runeSkillsCache.get(runeID).put(token, amount);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,18 +9,8 @@
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.SkillReq;
|
||||
import engine.powers.PowersBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class dbSkillReqHandler extends dbHandlerBase {
|
||||
|
||||
@@ -28,72 +18,4 @@ public class dbSkillReqHandler extends dbHandlerBase {
|
||||
this.localClass = SkillReq.class;
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public static ArrayList<PowersBase> getAllPowersBase() {
|
||||
|
||||
ArrayList<PowersBase> powerBaseList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_powerbase")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
PowersBase toAdd = new PowersBase(rs);
|
||||
powerBaseList.add(toAdd);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return powerBaseList;
|
||||
}
|
||||
|
||||
public static void getFailConditions(HashMap<String, PowersBase> powers) {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT IDString, type FROM static_power_failcondition where powerOrEffect = 'Power'")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
String type = rs.getString("type");
|
||||
String IDString = rs.getString("IDString");
|
||||
PowersBase pb = powers.get(IDString);
|
||||
|
||||
if (pb != null)
|
||||
switch (type) {
|
||||
case "CastSpell":
|
||||
pb.cancelOnCastSpell = true;
|
||||
break;
|
||||
case "TakeDamage":
|
||||
pb.cancelOnTakeDamage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<SkillReq> GET_REQS_FOR_RUNE(final int objectUUID) {
|
||||
|
||||
ArrayList<SkillReq> skillReqsList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_skill_skillreq` WHERE `runeID`=?")) {
|
||||
|
||||
preparedStatement.setInt(1, objectUUID);
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
skillReqsList = getObjectsFromRs(rs, 5);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return skillReqsList;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class dbStaticWorldHandler extends dbHandlerBase {
|
||||
|
||||
public dbStaticWorldHandler() {
|
||||
|
||||
}
|
||||
|
||||
// Table and column come from StaticManifest's fixed list, never from input. -1 means "none" and is skipped.
|
||||
public HashMap<Integer, Integer> GET_NEGATIVE_REFERENCES(String table, String column) {
|
||||
|
||||
HashMap<Integer, Integer> rowsByValue = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `" + column + "` AS `value`, COUNT(*) AS `rows` FROM `"
|
||||
+ table + "` WHERE `" + column + "` < -1 GROUP BY `" + column + "`;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
rowsByValue.put(rs.getInt("value"), rs.getInt("rows"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(table + "." + column + ": " + e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return rowsByValue;
|
||||
}
|
||||
|
||||
// Leader NPC of each DB NPC guild by guild name. Interim owner source for static buildings until the
|
||||
// static guilds get their own leaders (World Boot Plan 2.5/3.2).
|
||||
public HashMap<String, Integer> GET_NPC_GUILD_LEADERS() {
|
||||
|
||||
HashMap<String, Integer> leadersByName = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_guild`.`name`, `obj_guild`.`leaderUID` FROM `obj_guild` "
|
||||
+ "INNER JOIN `object` ON `object`.`UID` = `obj_guild`.`leaderUID` WHERE `object`.`type` = 'npc';")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next())
|
||||
leadersByName.put(rs.getString("name"), rs.getInt("leaderUID"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return leadersByName;
|
||||
}
|
||||
|
||||
// obj_zone rows built by the import procedures; 0 once the 2.4 migration has run, -1 on error.
|
||||
public int COUNT_STATIC_ZONE_ROWS() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT COUNT(*) AS `zones` FROM `obj_zone` WHERE `template` <> 0;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
if (rs.next())
|
||||
return rs.getInt("zones");
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// NPC cities still in obj_city; 0 once the 2.5 migration has run, -1 on error.
|
||||
public int COUNT_NPC_CITY_ROWS() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT COUNT(*) AS `cities` FROM `obj_city` WHERE `isNpc` = 1;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
if (rs.next())
|
||||
return rs.getInt("cities");
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import engine.objects.Warehouse;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.joda.time.DateTime;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -134,7 +135,6 @@ public class dbWarehouseHandler extends dbHandlerBase {
|
||||
|
||||
while (rs.next()) {
|
||||
int cityUID = rs.getInt("cityUUID");
|
||||
JSONObject jsonObject = new JSONObject(rs.getString("warehouse"));
|
||||
City city = City.getCity(cityUID);
|
||||
|
||||
if (city == null) {
|
||||
@@ -142,12 +142,18 @@ public class dbWarehouseHandler extends dbHandlerBase {
|
||||
continue;
|
||||
}
|
||||
|
||||
city.warehouse = new Warehouse(jsonObject);
|
||||
try {
|
||||
city.warehouse = new Warehouse(new JSONObject(rs.getString("warehouse")));
|
||||
} catch (JSONException e) {
|
||||
Logger.error("Warehouse for city " + cityUID + " failed to load: " + e.getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
city.warehouse.city = city;
|
||||
|
||||
// Locate warehouse building
|
||||
for (Building building : city.parentZone.zoneBuildingSet) {
|
||||
if (building.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.WAREHOUSE)) {
|
||||
if (building.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.WAREHOUSE) && building.getRank() != -1) {
|
||||
city.warehouse.building = building;
|
||||
break;
|
||||
}
|
||||
@@ -205,8 +211,16 @@ public class dbWarehouseHandler extends dbHandlerBase {
|
||||
ResultSet rs = preparedStatement.executeQuery()) {
|
||||
|
||||
while (rs.next()) {
|
||||
JSONObject jsonObject = new JSONObject(rs.getString("workorder"));
|
||||
WorkOrder workOrder = new WorkOrder(jsonObject);
|
||||
int workOrderID = rs.getInt("workorderID");
|
||||
WorkOrder workOrder;
|
||||
|
||||
try {
|
||||
workOrder = new WorkOrder(new JSONObject(rs.getString("workorder")));
|
||||
} catch (JSONException e) {
|
||||
Logger.error("WorkOrder " + workOrderID + " failed to load: " + e.getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
submitList.add(workOrder);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -10,10 +10,8 @@
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.Zone;
|
||||
import engine.objects.ZoneTemplate;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -46,6 +44,23 @@ public class dbZoneHandler extends dbHandlerBase {
|
||||
return zoneList;
|
||||
}
|
||||
|
||||
public ArrayList<Zone> GET_PLAYER_CITY_ZONES() {
|
||||
|
||||
ArrayList<Zone> zoneList = new ArrayList<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` WHERE `obj_zone`.`template` = 0 ORDER BY `object`.`UID` ASC;")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
zoneList = getObjectsFromRs(rs, 200);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return zoneList;
|
||||
}
|
||||
|
||||
public Zone GET_BY_UID(long ID) {
|
||||
|
||||
Zone zone = (Zone) DbManager.getFromCache(mbEnums.GameObjectType.Zone, (int) ID);
|
||||
@@ -68,54 +83,12 @@ public class dbZoneHandler extends dbHandlerBase {
|
||||
return zone;
|
||||
}
|
||||
|
||||
public void LOAD_ALL_ZONE_TEMPLATES() {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_zone_templates")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
ZoneTemplate zoneTemplate = new ZoneTemplate(rs);
|
||||
ZoneManager._zone_templates.put(zoneTemplate.templateID, zoneTemplate);
|
||||
}
|
||||
|
||||
// Add player city
|
||||
|
||||
ZoneTemplate zoneTemplate = new ZoneTemplate();
|
||||
|
||||
zoneTemplate.templateID = 0;
|
||||
zoneTemplate.sea_level_type = "PARENT";
|
||||
zoneTemplate.sea_level = 0;
|
||||
zoneTemplate.max_blend = 128;
|
||||
zoneTemplate.min_blend = 128;
|
||||
zoneTemplate.terrain_max_y = 5;
|
||||
zoneTemplate.major_radius = (int) mbEnums.CityBoundsType.ZONE.halfExtents;
|
||||
zoneTemplate.minor_radius = (int) mbEnums.CityBoundsType.ZONE.halfExtents;
|
||||
zoneTemplate.terrain_type = "PLANAR";
|
||||
|
||||
ZoneManager._zone_templates.put(zoneTemplate.templateID, zoneTemplate);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean DELETE_ZONE(final Zone zone) {
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `object` WHERE `UID` = ? AND `type` = 'zone'")) {
|
||||
if (DbManager.refuseStaticWrite(zone))
|
||||
return false;
|
||||
|
||||
preparedStatement.setInt(1, zone.getObjectUUID());
|
||||
|
||||
return (preparedStatement.executeUpdate() > 0);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
return deleteObjectTree(zone.getObjectUUID(), "zone") > 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.*;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -99,12 +100,18 @@ public abstract class AbstractDevCmd {
|
||||
if (args.length > 0 && args[0].equalsIgnoreCase("?")) {
|
||||
this.sendHelp(pcSender);
|
||||
this.sendUsage(pcSender);
|
||||
} else if (this.addsWorldContent()) {
|
||||
this.refuseWorldChange(pcSender, target);
|
||||
} else {
|
||||
this.tr = target;
|
||||
this._doCmd(pcSender, args, target);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean addsWorldContent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void _doCmd(PlayerCharacter pcSender, String[] args,
|
||||
AbstractGameObject target);
|
||||
|
||||
@@ -178,4 +185,22 @@ public abstract class AbstractDevCmd {
|
||||
ChatManager.chatSystemInfo(pc, msgText);
|
||||
}
|
||||
|
||||
// Static world objects are built from client data each boot, so they are changed with external tooling only.
|
||||
protected boolean refuseStaticTarget(PlayerCharacter pc, AbstractGameObject target) {
|
||||
|
||||
if (!(target instanceof AbstractWorldObject) || !((AbstractWorldObject) target).isStaticWorldObject())
|
||||
return false;
|
||||
|
||||
this.refuseWorldChange(pc, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void refuseWorldChange(PlayerCharacter pc, AbstractGameObject target) {
|
||||
|
||||
String targetText = (target == null) ? "no target" : target.getObjectType() + " " + target.getObjectUUID();
|
||||
|
||||
this.throwbackError(pc, "Must use external tooling to modify gameworld");
|
||||
Logger.info("Refused dev command " + this.getMainCmdString() + " on " + targetText + " by " + pc.getFirstName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Quaternion;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums.ProtectionState;
|
||||
import engine.objects.*;
|
||||
@@ -54,8 +54,7 @@ public class AddBuildingCmd extends AbstractDevCmd {
|
||||
"Invalid addBuilding Command. Invalid Building ID.");
|
||||
return;
|
||||
}
|
||||
Vector3f rot = new Vector3f(0.0f, 0.0f, 0.0f);
|
||||
float w = 1f;
|
||||
Quaternion rotation = new Quaternion();
|
||||
Zone zone = ZoneManager.findSmallestZone(pc.getLoc());
|
||||
|
||||
if (zone == null) {
|
||||
@@ -73,8 +72,7 @@ public class AddBuildingCmd extends AbstractDevCmd {
|
||||
Building likeBuilding = DbManager.BuildingQueries.GET_BUILDING_BY_MESH(ID);
|
||||
|
||||
if (likeBuilding != null) {
|
||||
rot = likeBuilding.getRot();
|
||||
w = likeBuilding.getw();
|
||||
rotation = likeBuilding.getRotation();
|
||||
}
|
||||
|
||||
String buildingName = "";
|
||||
@@ -90,11 +88,10 @@ public class AddBuildingCmd extends AbstractDevCmd {
|
||||
blueprintUUID = blueprint.getBlueprintUUID();
|
||||
}
|
||||
|
||||
Building building = DbManager.BuildingQueries.
|
||||
CREATE_BUILDING(
|
||||
zone.getObjectUUID(), 0, buildingName, ID,
|
||||
localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, rank,
|
||||
null, blueprintUUID, w, rot.y);
|
||||
Building building = Building.persistBuilding(Building.createBuilding(
|
||||
zone, 0, buildingName, ID,
|
||||
localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, rank,
|
||||
null, blueprintUUID, rotation.w, rotation.y));
|
||||
|
||||
|
||||
if (building == null) {
|
||||
@@ -102,9 +99,6 @@ public class AddBuildingCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
|
||||
building.setRot(rot);
|
||||
building.setw(w);
|
||||
|
||||
building.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
|
||||
WorldGrid.addObject(building, pc);
|
||||
ChatManager.chatSayInfo(pc,
|
||||
@@ -114,6 +108,11 @@ public class AddBuildingCmd extends AbstractDevCmd {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean addsWorldContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getHelpString() {
|
||||
return "Creates a building of type 'buildingID' at the location your character is standing.";
|
||||
|
||||
@@ -75,6 +75,11 @@ public class AddMobCmd extends AbstractDevCmd {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean addsWorldContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getHelpString() {
|
||||
return "Creates a Mob of type 'mobID' at the location your character is standing";
|
||||
|
||||
@@ -94,6 +94,11 @@ public class AddNPCCmd extends AbstractDevCmd {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean addsWorldContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getHelpString() {
|
||||
return "Creates an NPC of type 'npcID' at the location your character is standing";
|
||||
|
||||
@@ -15,8 +15,8 @@ import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
/**
|
||||
@@ -38,7 +38,7 @@ public class CreateItemCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
int templateID = Integer.parseInt(words[0]);
|
||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(templateID);
|
||||
|
||||
if (template == null) {
|
||||
ChatManager.chatSystemInfo(playerCharacter, "No such template found.");
|
||||
@@ -51,7 +51,7 @@ public class CreateItemCmd extends AbstractDevCmd {
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
if (!playerCharacter.charItemManager.hasRoomInventory(template.item_wt)) {
|
||||
if (!playerCharacter.charItemManager.hasRoomInventory(template.getItemWt())) {
|
||||
ChatManager.chatSystemInfo(playerCharacter, "You are encumbered!.");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.City;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.objects.Warehouse;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class FillCmd extends AbstractDevCmd {
|
||||
|
||||
public FillCmd() {
|
||||
super("fill");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _doCmd(PlayerCharacter pc, String[] words,
|
||||
AbstractGameObject target) {
|
||||
|
||||
Building building;
|
||||
City city;
|
||||
Warehouse warehouse;
|
||||
int amount = Integer.MAX_VALUE;
|
||||
HashMap<mbEnums.ResourceType, Integer> oldResources;
|
||||
|
||||
if (words.length > 1) {
|
||||
this.sendUsage(pc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (words.length == 1 && !words[0].isEmpty()) {
|
||||
try {
|
||||
amount = Integer.parseInt(words[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
throwbackError(pc, "Amount must be a number, " + words[0] + " is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount < 0) {
|
||||
throwbackError(pc, "Amount must be 0 or more");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (target == null || target.getObjectType() != mbEnums.GameObjectType.Building) {
|
||||
throwbackError(pc, "Select a warehouse");
|
||||
return;
|
||||
}
|
||||
|
||||
building = (Building) target;
|
||||
|
||||
if (building.getBlueprint() == null || building.getBlueprint().getBuildingGroup() != mbEnums.BuildingGroup.WAREHOUSE) {
|
||||
throwbackError(pc, "Selected building is not a warehouse");
|
||||
return;
|
||||
}
|
||||
|
||||
city = building.getCity();
|
||||
|
||||
if (city == null || city.warehouse == null || city.warehouse.building == null
|
||||
|| city.warehouse.building.getObjectUUID() != building.getObjectUUID()) {
|
||||
throwbackError(pc, "Selected warehouse is not the active warehouse of a city");
|
||||
return;
|
||||
}
|
||||
|
||||
warehouse = city.warehouse;
|
||||
|
||||
oldResources = new HashMap<>(warehouse.resources);
|
||||
|
||||
for (mbEnums.ResourceType resourceType : mbEnums.ResourceType.values())
|
||||
warehouse.resources.put(resourceType, Math.min(amount, resourceType.deposit_limit));
|
||||
|
||||
if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) {
|
||||
warehouse.resources.putAll(oldResources);
|
||||
throwbackError(pc, "Failed to update the warehouse in the database");
|
||||
return;
|
||||
}
|
||||
|
||||
ChatManager.chatSayInfo(pc, "Filled the " + city.getCityName() + " warehouse"
|
||||
+ (amount == Integer.MAX_VALUE ? " to each deposit limit" : " with " + amount + " of each resource (capped at the deposit limit)"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getHelpString() {
|
||||
return "Sets every resource in the selected warehouse";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getUsageString() {
|
||||
return "' ./fill [amount]' with a warehouse selected (no amount fills each resource to its deposit limit)";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,8 +37,8 @@ public class GetHeightCmd extends AbstractDevCmd {
|
||||
|
||||
Vector2f childZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), heightmapZone);
|
||||
Vector2f childZoneOffset = ZoneManager.worldToZoneOffset(playerCharacter.getLoc(), heightmapZone);
|
||||
Vector2f normalizedOffset = new Vector2f(Math.abs(childZoneOffset.x) / heightmapZone.template.major_radius,
|
||||
Math.abs(childZoneOffset.y) / heightmapZone.template.minor_radius);
|
||||
Vector2f normalizedOffset = new Vector2f(Math.abs(childZoneOffset.x) / heightmapZone.template.zone_major_radius,
|
||||
Math.abs(childZoneOffset.y) / heightmapZone.template.zone_minor_radius);
|
||||
Vector2f parentZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), parentZone);
|
||||
|
||||
float childHeight = heightmapZone.terrain.getInterpolatedTerrainHeight(childZoneLoc);
|
||||
@@ -74,7 +74,7 @@ public class GetHeightCmd extends AbstractDevCmd {
|
||||
|
||||
this.throwbackInfo(playerCharacter, "Child Zone Offset: " + "[" + childZoneOffset.x + "]" + "[" + childZoneOffset.y + "]");
|
||||
this.throwbackInfo(playerCharacter, "Normalized offset: " + "[" + normalizedOffset.x + "]" + "[" + normalizedOffset.y + "]");
|
||||
this.throwbackInfo(playerCharacter, "template blend Values: (max/min): " + heightmapZone.template.max_blend + " /" + heightmapZone.template.min_blend);
|
||||
this.throwbackInfo(playerCharacter, "template blend Values: (max/min): " + heightmapZone.template.zone_max_blend + " /" + heightmapZone.template.zone_min_blend);
|
||||
this.throwbackInfo(playerCharacter, "terrain values (max/min): " + heightmapZone.terrain.blend_values.x + " /" + heightmapZone.terrain.blend_values.y);
|
||||
this.throwbackInfo(playerCharacter, "Blend coefficient: " + heightmapZone.terrain.getTerrainBlendCoefficient(childZoneOffset));
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import engine.mbEnums.BuildingGroup;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.mbEnums.TargetColor;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.StringUtils;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
@@ -87,7 +89,7 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
output += newline;
|
||||
output += StringUtils.addWS("Alt: " + targetLoc.y, 20);
|
||||
output += newline;
|
||||
output += "Rot: " + targetAWO.getRot().y;
|
||||
output += "Rot: " + targetAWO.getRotation().y;
|
||||
output += newline;
|
||||
double radian = 0;
|
||||
|
||||
@@ -105,7 +107,7 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
case Building:
|
||||
Building targetBuilding = (Building) target;
|
||||
output += StringUtils.addWS("Lac: "
|
||||
+ targetBuilding.getw(), 20);
|
||||
+ targetBuilding.getRotation().w, 20);
|
||||
output += "Blueprint : ";
|
||||
output += targetBuilding.getBlueprintUUID();
|
||||
output += newline;
|
||||
@@ -342,7 +344,7 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
|
||||
case NPC:
|
||||
NPC targetNPC = (NPC) target;
|
||||
output += "databaseID: " + targetNPC.getDBID() + newline;
|
||||
output += "databaseID: " + databaseIDText(targetNPC.getDBID()) + newline;
|
||||
output += "Name: " + targetNPC.getName();
|
||||
output += newline;
|
||||
output += StringUtils.addWS("Level: " + targetNPC.getLevel(), 20);
|
||||
@@ -413,7 +415,7 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
break;
|
||||
case Mob:
|
||||
Mob targetMob = (Mob) target;
|
||||
output += "databaseID: " + targetMob.getDBID() + newline;
|
||||
output += "databaseID: " + databaseIDText(targetMob.getDBID()) + newline;
|
||||
output += "Name: " + targetMob.getName();
|
||||
output += newline;
|
||||
output += StringUtils.addWS("Level: " + targetMob.getLevel(), 20);
|
||||
@@ -507,17 +509,17 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
case Item: //intentional passthrough
|
||||
case MobLoot:
|
||||
Item item = (Item) target;
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
output += StringUtils.addWS("Template: " + template.template_id, 20);
|
||||
output += "Weight: " + template.item_wt;
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
output += StringUtils.addWS("Template: " + template.getTemplateId(), 20);
|
||||
output += "Weight: " + template.getItemWt();
|
||||
output += newline;
|
||||
DecimalFormat df = new DecimalFormat("###,###,###,###,##0");
|
||||
output += StringUtils.addWS("Qty: "
|
||||
+ df.format(item.getNumOfItems()), 20);
|
||||
output += "Charges: " + (byte) item.chargesRemaining
|
||||
+ '/' + item.template.item_initial_charges;
|
||||
+ '/' + item.template.getItemInitialCharges();
|
||||
output += newline;
|
||||
output += "Name: " + template.item_base_name;
|
||||
output += "Name: " + template.getItemBaseName();
|
||||
output += newline;
|
||||
output += item.getContainerInfo();
|
||||
|
||||
@@ -538,6 +540,14 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
throwbackInfo(pc, output);
|
||||
}
|
||||
|
||||
private static String databaseIDText(int databaseID) {
|
||||
|
||||
if (databaseID == MBServerStatics.NO_DB_ROW_ASSIGNED_YET)
|
||||
return "none";
|
||||
|
||||
return String.valueOf(databaseID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getHelpString() {
|
||||
return "Gets information on an Object.";
|
||||
|
||||
@@ -11,9 +11,11 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums.ItemContainerType;
|
||||
import engine.mbEnums.ItemType;
|
||||
import engine.mbEnums.OwnerType;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
|
||||
/**
|
||||
@@ -59,18 +61,17 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
int templateID;
|
||||
ItemTemplate template;
|
||||
CObjectTemplate template;
|
||||
try {
|
||||
templateID = Integer.parseInt(words[0]);
|
||||
template = ItemTemplate.templates.get(words[0].toLowerCase());
|
||||
template = CObjectTemplate.lookup(templateID);
|
||||
|
||||
if (template == null) {
|
||||
throwbackError(pc, "Supplied type " + words[0]
|
||||
+ " failed to parse to an Integer");
|
||||
throwbackError(pc, "No item template with id " + words[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (template.item_type == ItemType.GOLD) {
|
||||
if (template.getItemType() == ItemType.GOLD) {
|
||||
this.throwbackInfo(pc, "use /addgold to add gold.");
|
||||
return;
|
||||
}
|
||||
@@ -132,7 +133,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
}
|
||||
template = ItemTemplate.templates.get(templateID);
|
||||
template = CObjectTemplate.lookup(templateID);
|
||||
|
||||
if (template == null) {
|
||||
throwbackError(pc, "Unable to find template " + templateID);
|
||||
@@ -140,8 +141,8 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
if ((numItems > 1)
|
||||
&& (template.item_type.equals(ItemType.RESOURCE) == false)
|
||||
&& (template.item_type.equals(ItemType.OFFERING)) == false)
|
||||
&& (template.getItemType().equals(ItemType.RESOURCE) == false)
|
||||
&& (template.getItemType().equals(ItemType.OFFERING)) == false)
|
||||
numItems = 1;
|
||||
|
||||
CharacterItemManager cim = pc.charItemManager;
|
||||
@@ -155,7 +156,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
|
||||
for (int i = 0; i < quantity; i++) {
|
||||
|
||||
int weight = template.item_wt;
|
||||
int weight = template.getItemWt();
|
||||
|
||||
if (!cim.hasRoomInventory(weight)) {
|
||||
throwbackError(pc, "Not enough room in inventory for any more of this item. " + i + " produced.");
|
||||
@@ -169,6 +170,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
Item item = new Item(templateID);
|
||||
item.ownerID = pc.getObjectUUID();
|
||||
item.ownerType = OwnerType.PlayerCharacter;
|
||||
item.containerType = ItemContainerType.INVENTORY;
|
||||
|
||||
if (numItems > 1)
|
||||
item.setNumOfItems(numItems);
|
||||
@@ -180,6 +182,11 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == null) {
|
||||
throwbackError(pc, "DB error 2: Unable to create item " + templateID + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
//create prefix
|
||||
if (!prefix.isEmpty())
|
||||
item.addPermanentEnchantmentForDev(prefix, 0);
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -52,8 +53,8 @@ public class PrintBankCmd extends AbstractDevCmd {
|
||||
throwbackInfo(pc, "Bank for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
|
||||
for (Item item : list) {
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems());
|
||||
}
|
||||
|
||||
Item gold = cim.getGoldBank();
|
||||
|
||||
@@ -13,6 +13,7 @@ import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
|
||||
public class PrintBonusesCmd extends AbstractDevCmd {
|
||||
@@ -33,8 +34,8 @@ public class PrintBonusesCmd extends AbstractDevCmd {
|
||||
if (target instanceof Item) {
|
||||
type = "Item";
|
||||
tar = (Item) target;
|
||||
ItemTemplate template = ItemTemplate.templates.get(((Item) tar).templateID);
|
||||
name = template.item_base_name;
|
||||
CObjectTemplate template = CObjectTemplate.lookup(((Item) tar).templateID);
|
||||
name = template.getItemBaseName();
|
||||
} else if (target instanceof AbstractCharacter) {
|
||||
tar = (AbstractCharacter) target;
|
||||
name = ((AbstractCharacter) tar).getFirstName();
|
||||
|
||||
@@ -10,9 +10,15 @@
|
||||
package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.Effect;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.PowersBase;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -30,28 +36,60 @@ public class PrintEffectsCmd extends AbstractDevCmd {
|
||||
AbstractGameObject target) {
|
||||
|
||||
AbstractCharacter tar;
|
||||
StringBuilder output;
|
||||
String newline = "\r\n ";
|
||||
Effect effect;
|
||||
EffectsBase effectsBase;
|
||||
PowersBase power;
|
||||
|
||||
if (target != null && target instanceof AbstractCharacter) {
|
||||
tar = (AbstractCharacter) target;
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
String newline = "\r\n ";
|
||||
String output = "Effects For Character: " + tar.getName() + newline;
|
||||
if (target.getObjectType() != GameObjectType.PlayerCharacter && target.getObjectType() != GameObjectType.Mob
|
||||
&& target.getObjectType() != GameObjectType.NPC)
|
||||
return;
|
||||
|
||||
for (String effect : tar.effects.keySet()) {
|
||||
output += effect + newline;
|
||||
}
|
||||
throwbackInfo(pc, output);
|
||||
tar = (AbstractCharacter) target;
|
||||
output = new StringBuilder("Effects for " + tar.getName() + " (" + tar.effects.size() + "):" + newline);
|
||||
|
||||
// Keys are the effect UUID for mobbase/rune effects, or the stack type (e.g. PetBuff) for power effects
|
||||
for (Map.Entry<String, Effect> entry : tar.effects.entrySet()) {
|
||||
|
||||
effect = entry.getValue();
|
||||
effectsBase = effect.getEffectsBase();
|
||||
power = effect.getPower();
|
||||
|
||||
output.append(entry.getKey()).append(": ");
|
||||
|
||||
if (effectsBase != null)
|
||||
output.append(effectsBase.getIDString()).append(" '").append(effectsBase.getName()).append("'");
|
||||
else
|
||||
output.append("no EffectsBase");
|
||||
|
||||
output.append(" rank ").append(effect.getTrains());
|
||||
|
||||
if (effect.isStatic())
|
||||
output.append(", static");
|
||||
else
|
||||
output.append(", ").append((int) effect.getDuration()).append("s left");
|
||||
|
||||
if (power != null)
|
||||
output.append(", from ").append(power.getIDString()).append(" '").append(power.getName()).append("'");
|
||||
|
||||
output.append(newline);
|
||||
}
|
||||
|
||||
throwbackInfo(pc, output.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getHelpString() {
|
||||
return "Returns the player's current stats";
|
||||
return "Lists the target's effects: key, effect id and name, rank, time left and source power";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getUsageString() {
|
||||
return "' /printstats'";
|
||||
return "' /printeffects'";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
||||
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
||||
Item equip = tarMob.charItemManager.equipped.get(slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
||||
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
||||
Item equip = tarMob.charItemManager.equipped.get(slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
||||
|
||||
for (mbEnums.EquipSlotType slot : list.keySet()) {
|
||||
Item item = list.get(slot);
|
||||
throwbackInfo(pc, " " + item.template.item_base_name + ", slot: " + slot);
|
||||
throwbackInfo(pc, " " + item.template.getItemBaseName() + ", slot: " + slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package engine.devcmd.cmds;
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.mbEnums.ItemType;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
@@ -75,18 +76,18 @@ public class PrintInventoryCmd extends AbstractDevCmd {
|
||||
int goldCount = 0;
|
||||
|
||||
for (Item item : inventory) {
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
|
||||
if (item.template.item_type.equals(ItemType.GOLD) == false) {
|
||||
if (item.template.getItemType().equals(ItemType.GOLD) == false) {
|
||||
|
||||
String chargeInfo = "";
|
||||
int chargeMax = template.item_initial_charges;
|
||||
int chargeMax = template.getItemInitialCharges();
|
||||
|
||||
if (chargeMax > 0) {
|
||||
int charges = item.chargesRemaining;
|
||||
chargeInfo = " charges: " + charges + '/' + chargeMax;
|
||||
}
|
||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems() + chargeInfo);
|
||||
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems() + chargeInfo);
|
||||
} else
|
||||
goldCount += item.getNumOfItems();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -50,8 +51,8 @@ public class PrintVaultCmd extends AbstractDevCmd {
|
||||
ArrayList<Item> list = cim.getVault();
|
||||
throwbackInfo(pc, "Vault for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
for (Item item : list) {
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems());
|
||||
}
|
||||
Item gold = cim.getGoldVault();
|
||||
if (gold != null)
|
||||
|
||||
@@ -66,6 +66,9 @@ public class PullCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.refuseStaticTarget(pcSender, target))
|
||||
return;
|
||||
|
||||
targetLoc = pcSender.getLoc();
|
||||
serverZone = ZoneManager.findSmallestZone(targetLoc);
|
||||
switch (target.getObjectType()) {
|
||||
|
||||
@@ -245,11 +245,17 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
|
||||
|
||||
HashSet<AbstractWorldObject> objectList =
|
||||
WorldGrid.getObjectsInRangePartial(_currentLocation, _targetRange, _targetMask);
|
||||
int staticSkipped = 0;
|
||||
|
||||
// Iterate through array and remove objects from game world and database
|
||||
|
||||
for (AbstractWorldObject awo : objectList) {
|
||||
|
||||
if (awo.isStaticWorldObject()) {
|
||||
staticSkipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (awo.getObjectType()) {
|
||||
case Building:
|
||||
removeBuilding(pc, (Building) awo);
|
||||
@@ -266,7 +272,8 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
// Send results to user
|
||||
throwbackInfo(pc, "Purge: " + objectList.size() + " objects were removed in range " + _targetRange);
|
||||
throwbackInfo(pc, "Purge: " + (objectList.size() - staticSkipped) + " objects were removed in range " + _targetRange
|
||||
+ ", " + staticSkipped + " static objects skipped");
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
@@ -119,6 +119,9 @@ public class RemoveObjectCmd extends AbstractDevCmd {
|
||||
|
||||
private void removeBuilding(PlayerCharacter pc, Building building) {
|
||||
|
||||
if (this.refuseStaticTarget(pc, building))
|
||||
return;
|
||||
|
||||
Zone currentZone = ZoneManager.findSmallestZone(pc.getLoc());
|
||||
|
||||
if (currentZone == null) {
|
||||
@@ -164,6 +167,9 @@ public class RemoveObjectCmd extends AbstractDevCmd {
|
||||
|
||||
private void removeNPC(PlayerCharacter pc, NPC npc) {
|
||||
|
||||
if (this.refuseStaticTarget(pc, npc))
|
||||
return;
|
||||
|
||||
Zone currentZone = ZoneManager.findSmallestZone(pc.getLoc());
|
||||
if (currentZone == null) {
|
||||
this.throwbackError(pc, "Could not locate zone for player.");
|
||||
@@ -196,6 +202,9 @@ public class RemoveObjectCmd extends AbstractDevCmd {
|
||||
|
||||
private void removeMob(PlayerCharacter pc, Mob mob) {
|
||||
|
||||
if (this.refuseStaticTarget(pc, mob))
|
||||
return;
|
||||
|
||||
Zone currentZone = ZoneManager.findSmallestZone(pc.getLoc());
|
||||
|
||||
if (currentZone == null) {
|
||||
|
||||
@@ -47,6 +47,10 @@ public class RenameCmd extends AbstractDevCmd {
|
||||
building = (Building) target;
|
||||
} else
|
||||
npc = getTargetAsNPC(pcSender);
|
||||
|
||||
if (this.refuseStaticTarget(pcSender, npc) || this.refuseStaticTarget(pcSender, building))
|
||||
return;
|
||||
|
||||
if (npc != null) {
|
||||
DbManager.NPCQueries.SET_PROPERTY(npc, "npc_name", args[0]);
|
||||
String name = args[0];
|
||||
|
||||
@@ -14,7 +14,8 @@ import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.FastMath;
|
||||
import engine.math.Quaternion;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.*;
|
||||
|
||||
@@ -63,14 +64,12 @@ public class RotateCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3f rotation = new Vector3f(0f, rot, 0f);
|
||||
|
||||
if (target instanceof Building)
|
||||
rotateBuilding(pc, (Building) target, rotation, rot, false);
|
||||
rotateBuilding(pc, (Building) target, (float) Math.toRadians(rot));
|
||||
else if (target instanceof NPC)
|
||||
rotateNPC(pc, (NPC) target, rotation, false);
|
||||
rotateNPC(pc, (NPC) target, (float) Math.toRadians(rot));
|
||||
else if (target instanceof Mob)
|
||||
rotateMob(pc, (Mob) target, rotation, false);
|
||||
rotateMob(pc, (Mob) target, (float) Math.toRadians(rot));
|
||||
else
|
||||
throwbackError(pc, "Target " + target.getObjectType()
|
||||
+ " is not a valid object type");
|
||||
@@ -141,15 +140,13 @@ public class RotateCmd extends AbstractDevCmd {
|
||||
}
|
||||
}
|
||||
|
||||
Vector3f rotation = new Vector3f(0f, rot, 0f);
|
||||
|
||||
Building b;
|
||||
if (id != 0)
|
||||
b = BuildingManager.getBuilding(id);
|
||||
else
|
||||
b = getTargetAsBuilding(pc);
|
||||
if (b != null) {
|
||||
rotateBuilding(pc, b, rotation, rot, false);
|
||||
rotateBuilding(pc, b, (float) Math.toRadians(rot));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -160,7 +157,7 @@ public class RotateCmd extends AbstractDevCmd {
|
||||
else
|
||||
npc = getTargetAsNPC(pc);
|
||||
if (npc != null) {
|
||||
rotateNPC(pc, npc, rotation, false);
|
||||
rotateNPC(pc, npc, (float) Math.toRadians(rot));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -171,7 +168,7 @@ public class RotateCmd extends AbstractDevCmd {
|
||||
else
|
||||
mob = getTargetAsMob(pc);
|
||||
if (mob != null) {
|
||||
rotateMob(pc, mob, rotation, false);
|
||||
rotateMob(pc, mob, (float) Math.toRadians(rot));
|
||||
return;
|
||||
}
|
||||
throwbackError(pc, "Nothing found to rotate.");
|
||||
@@ -185,40 +182,52 @@ public class RotateCmd extends AbstractDevCmd {
|
||||
|
||||
@Override
|
||||
protected String _getUsageString() {
|
||||
return "' /rotate [objectID] rotation' || ' /rot [objectID] rotation'";
|
||||
return "' /rotate [objectID] degrees' || ' /rot [objectID] degrees' || ' /rotate face'";
|
||||
}
|
||||
|
||||
private void rotateBuilding(PlayerCharacter pc, Building building, Vector3f rot, float orig, boolean faceDirection) {
|
||||
if (!faceDirection)
|
||||
rot.set(0.0f, (float) Math.sin(Math.toRadians(orig) / 2), 0.0f);
|
||||
building.setRot(rot);
|
||||
building.setw((float) Math.abs(Math.cos(Math.toRadians(orig) / 2)));
|
||||
private void rotateBuilding(PlayerCharacter pc, Building building, float yaw) {
|
||||
|
||||
if (this.refuseStaticTarget(pc, building))
|
||||
return;
|
||||
|
||||
building.setRotation(Quaternion.fromYaw(yaw));
|
||||
building.getBounds().setBounds(building);
|
||||
WorldGrid.updateObject(building, pc);
|
||||
DbManager.BuildingQueries.SET_PROPERTY(building, "rotY", building.getRot().getY());
|
||||
DbManager.BuildingQueries.SET_PROPERTY(building, "w", building.getw());
|
||||
DbManager.BuildingQueries.SET_PROPERTY(building, "rotY", building.getRotation().y);
|
||||
DbManager.BuildingQueries.SET_PROPERTY(building, "w", building.getRotation().w);
|
||||
ChatManager.chatSayInfo(pc,
|
||||
"Building with ID " + building.getObjectUUID() + " rotated");
|
||||
}
|
||||
|
||||
private void rotateNPC(PlayerCharacter pc, NPC npc, Vector3f rot, boolean faceDirection) {
|
||||
npc.setRot(rot);
|
||||
DbManager.NPCQueries.SET_PROPERTY(npc, "npc_rotation", rot.y);
|
||||
private void rotateNPC(PlayerCharacter pc, NPC npc, float yaw) {
|
||||
|
||||
if (this.refuseStaticTarget(pc, npc))
|
||||
return;
|
||||
|
||||
npc.setRotation(characterRotation(yaw));
|
||||
DbManager.NPCQueries.SET_PROPERTY(npc, "npc_rotation", npc.getRotation().w);
|
||||
WorldGrid.updateObject(npc, pc);
|
||||
//no rotation for npc's in db currently
|
||||
ChatManager.chatSayInfo(pc,
|
||||
"NPC with ID " + npc.getObjectUUID() + " rotated");
|
||||
}
|
||||
|
||||
private void rotateMob(PlayerCharacter pc, Mob mob, Vector3f rot, boolean faceDirection) {
|
||||
mob.setRot(rot);
|
||||
DbManager.MobQueries.SET_PROPERTY(mob, "mob_rotation", rot.y);
|
||||
private void rotateMob(PlayerCharacter pc, Mob mob, float yaw) {
|
||||
|
||||
if (this.refuseStaticTarget(pc, mob))
|
||||
return;
|
||||
|
||||
mob.setRotation(characterRotation(yaw));
|
||||
DbManager.MobQueries.SET_PROPERTY(mob, "mob_rotation", mob.getRotation().w);
|
||||
WorldGrid.updateObject(mob, pc);
|
||||
//no rotation for mobs's in db currently
|
||||
ChatManager.chatSayInfo(pc,
|
||||
"Mob with ID " + mob.getObjectUUID() + " rotated");
|
||||
}
|
||||
|
||||
// npc_rotation and mob_rotation store w = cos θ/2, which reloads to the same yaw only for θ in [0, 2π).
|
||||
private static Quaternion characterRotation(float yaw) {
|
||||
return Quaternion.fromYaw((float) (yaw - FastMath.TWO_PI * Math.floor(yaw / FastMath.TWO_PI)));
|
||||
}
|
||||
|
||||
private void rotateFace(PlayerCharacter pc, AbstractGameObject target) {
|
||||
AbstractWorldObject awo = (AbstractWorldObject) target;
|
||||
if (awo == null)
|
||||
@@ -230,19 +239,12 @@ public class RotateCmd extends AbstractDevCmd {
|
||||
|
||||
float rotangle = faceDirection.getRotation();
|
||||
|
||||
float rot = (float) Math.toDegrees(rotangle);
|
||||
|
||||
if (rot > 180)
|
||||
rot *= -1;
|
||||
|
||||
Vector3f buildingrotation = new Vector3f(0f, rot, 0f);
|
||||
Vector3f rotation = new Vector3f(0f, rotangle, 0f);
|
||||
if (target instanceof Building)
|
||||
rotateBuilding(pc, (Building) target, buildingrotation, rot, false);
|
||||
rotateBuilding(pc, (Building) target, rotangle);
|
||||
else if (target instanceof NPC)
|
||||
rotateNPC(pc, (NPC) target, rotation, true);
|
||||
rotateNPC(pc, (NPC) target, rotangle);
|
||||
else if (target instanceof Mob)
|
||||
rotateMob(pc, (Mob) target, rotation, true);
|
||||
rotateMob(pc, (Mob) target, rotangle);
|
||||
else
|
||||
throwbackError(pc, "Target " + target.getObjectType()
|
||||
+ " is not a valid object type");
|
||||
|
||||
@@ -66,6 +66,9 @@ public class SetBuildingAltitudeCmd extends AbstractDevCmd {
|
||||
|
||||
Building targetBuilding = (Building) target;
|
||||
|
||||
if (this.refuseStaticTarget(pc, targetBuilding))
|
||||
return;
|
||||
|
||||
|
||||
float altitude = 0;
|
||||
try {
|
||||
|
||||
@@ -36,6 +36,8 @@ public class SetForceRenameCityCmd extends AbstractDevCmd {
|
||||
City city = City.getCity(zone.playerCityUUID);
|
||||
if (city == null)
|
||||
return;
|
||||
if (this.refuseStaticTarget(pc, city))
|
||||
return;
|
||||
city.setForceRename(rename);
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@ public class SetGuildCmd extends AbstractDevCmd {
|
||||
targetNPC = getTargetAsNPC(pcSender);
|
||||
targetGuild = Guild.getGuild(Integer.parseInt(args[0]));
|
||||
|
||||
if (this.refuseStaticTarget(pcSender, targetNPC))
|
||||
return;
|
||||
|
||||
DbManager.NPCQueries.SET_PROPERTY(targetNPC, "npc_guildID", args[0]);
|
||||
targetNPC.setGuild(targetGuild);
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ public class SetNpcNameCmd extends AbstractDevCmd {
|
||||
|
||||
NPC npc = (NPC) target;
|
||||
|
||||
if (this.refuseStaticTarget(pc, npc))
|
||||
return;
|
||||
|
||||
String name = words[0];
|
||||
|
||||
NPC.UpdateName(npc, name);
|
||||
|
||||
@@ -35,6 +35,9 @@ public class SetOwnerCmd extends AbstractDevCmd {
|
||||
|
||||
_targetBuilding = getTargetAsBuilding(pcSender);
|
||||
|
||||
if (this.refuseStaticTarget(pcSender, _targetBuilding))
|
||||
return;
|
||||
|
||||
// if it's a tol change ownership of the city
|
||||
|
||||
if (_targetBuilding.getBlueprint() != null &&
|
||||
|
||||
@@ -51,6 +51,10 @@ public class SetRankCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
if (target != null) {
|
||||
|
||||
if (this.refuseStaticTarget(player, target))
|
||||
return;
|
||||
|
||||
switch (target.getObjectType()) {
|
||||
case Building:
|
||||
Building targetBuilding = (Building) target;
|
||||
@@ -99,6 +103,9 @@ public class SetRankCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.refuseStaticTarget(player, targetBuilding))
|
||||
return;
|
||||
|
||||
Blueprint blueprint = targetBuilding.getBlueprint();
|
||||
|
||||
if (blueprint == null) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import engine.gameManager.LootManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.loot.BootySetEntry;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -34,10 +35,10 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
if (mob.bootySet != 0) {
|
||||
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) {
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(entry.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(entry.templateID);
|
||||
|
||||
if (template != null)
|
||||
output += "[" + entry.bootyType + "] " + template.item_base_name + " [Chance] " + entry.dropChance + newline;
|
||||
output += "[" + entry.bootyType + "] " + template.getItemBaseName() + " [Chance] " + entry.dropChance + newline;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
try {
|
||||
mob.loadInventory();
|
||||
for (Item lootItem : mob.charItemManager.getInventory()) {
|
||||
switch (lootItem.template.item_type) {
|
||||
switch (lootItem.template.getItemType()) {
|
||||
case EMPLOYMENTCONTRACT: //CONTRACT
|
||||
Contracts.add(lootItem);
|
||||
break;
|
||||
|
||||
@@ -118,18 +118,17 @@ public class aiInfoCmd extends AbstractDevCmd {
|
||||
|
||||
ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
|
||||
|
||||
// Additional powers may come from the contract ID. This is to support
|
||||
// powers for player guards irrespective of the mobbase used.
|
||||
// Player guards also cast their captain contract's powers, irrespective of the mobbase used.
|
||||
|
||||
if (mob.isPlayerGuard()) {
|
||||
|
||||
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
|
||||
|
||||
if (mob.contract != null)
|
||||
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.contractUUID));
|
||||
contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.contractUUID));
|
||||
|
||||
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION))
|
||||
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.guardCaptain.contractUUID));
|
||||
contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID));
|
||||
|
||||
powerEntries.addAll(contractEntries);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import engine.mbEnums.BuildingGroup;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -30,6 +31,7 @@ import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@@ -43,6 +45,7 @@ public enum BuildingManager {
|
||||
public static HashMap<Integer, ConcurrentHashMap<Integer, BuildingFriends>> _buildingFriends = new HashMap<>();
|
||||
public static HashMap<Integer, ConcurrentHashMap<Integer, Condemned>> _buildingCondemned = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<Vector3fImmutable>> _buildingPatrolPoints = new HashMap<>();
|
||||
public static HashSet<Integer> _npcBuildingOwners = new HashSet<>();
|
||||
|
||||
public static int getAvailableSlot(Building building) {
|
||||
|
||||
@@ -199,31 +202,31 @@ public enum BuildingManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(1705032); // Elan Stone
|
||||
CObjectTemplate template = CObjectTemplate.lookup(1705032); // Elan Stone
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(template.item_wt))
|
||||
if (!player.charItemManager.hasRoomInventory(template.getItemWt()))
|
||||
return false;
|
||||
|
||||
if (!ItemManager.MakeItemForPlayer(template.template_id, player, amount))
|
||||
if (!ItemManager.MakeItemForPlayer(template.getTemplateId(), player, amount))
|
||||
return false;
|
||||
|
||||
shrine.setFavors(0);
|
||||
break;
|
||||
case WAREHOUSE:
|
||||
|
||||
City city = building.getCity();
|
||||
|
||||
if (city == null)
|
||||
return true;
|
||||
|
||||
Warehouse warehouse = city.warehouse;
|
||||
Warehouse warehouse = Warehouse.destroyedWarehouses.get(building.getObjectUUID());
|
||||
|
||||
if (warehouse == null)
|
||||
return false;
|
||||
|
||||
for (mbEnums.ResourceType resourceType : EnumSet.allOf(mbEnums.ResourceType.class)) {
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(resourceType.template.item_wt)) {
|
||||
CObjectTemplate resourceTemplate = CObjectTemplate.lookup(resourceType.templateID);
|
||||
|
||||
if (resourceTemplate == null)
|
||||
continue;
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(resourceTemplate.getItemWt())) {
|
||||
ChatManager.chatSystemInfo(player, "You can not carry any more of that item.");
|
||||
return false;
|
||||
}
|
||||
@@ -241,6 +244,9 @@ public enum BuildingManager {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Warehouse.isEmpty(warehouse))
|
||||
Warehouse.destroyedWarehouses.remove(building.getObjectUUID());
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -719,7 +725,7 @@ public enum BuildingManager {
|
||||
Vector3fImmutable bindLoc = null;
|
||||
|
||||
if (building == null)
|
||||
return mbEnums.Ruins.getRandomRuin().getLocation();
|
||||
return ZoneManager.getRandomRuinLocation();
|
||||
|
||||
bindLoc = building.getLoc();
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.handlers.ClientAdminCommandMsgHandler;
|
||||
import engine.net.client.msg.chat.*;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.server.world.WorldServer;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -535,12 +536,12 @@ public enum ChatManager {
|
||||
if (item != null) //Steal
|
||||
if (success) {
|
||||
String name = "";
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD))
|
||||
name = amount + " gold ";
|
||||
else {
|
||||
String vowels = "aeiou";
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
String iName = template.item_base_name;
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
String iName = template.getItemBaseName();
|
||||
if (iName.length() > 0)
|
||||
if (vowels.indexOf(iName.substring(0, 1).toLowerCase()) >= 0)
|
||||
name = "an " + iName + ' ';
|
||||
|
||||
@@ -18,6 +18,8 @@ import engine.net.client.msg.PowerProjectileMsg;
|
||||
import engine.net.client.msg.TargetedActionMsg;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.powers.DamageShield;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
import engine.powers.effectmodifiers.WeaponProcEffectModifier;
|
||||
@@ -26,6 +28,7 @@ import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -92,25 +95,25 @@ public enum CombatManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon == null && offWeapon != null && !offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//swing left hand only
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon == null && offWeapon != null && offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//no weapon equipped with a shield, punch with one hand
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon != null && offWeapon != null && offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//one weapon equipped with a shield, swing with one hand
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon != null && offWeapon != null && !offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//two weapons equipped, swing both hands
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
|
||||
@@ -146,7 +149,7 @@ public enum CombatManager {
|
||||
if (bonus != null)
|
||||
rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None);
|
||||
|
||||
attackRange += weapon.template.item_weapon_max_range * rangeMod;
|
||||
attackRange += engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * rangeMod;
|
||||
} else if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
|
||||
|
||||
//unarmed mob, add the natural attack range from its rune (0 for most melee mobs)
|
||||
@@ -211,7 +214,7 @@ public enum CombatManager {
|
||||
|
||||
if (weapon != null) {
|
||||
|
||||
float wepSpeed = (int) (weapon.template.item_weapon_wepspeed);
|
||||
float wepSpeed = (int) (engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed);
|
||||
|
||||
if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus
|
||||
wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None));
|
||||
@@ -270,13 +273,13 @@ public enum CombatManager {
|
||||
if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
|
||||
//check if Out of Stamina
|
||||
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
|
||||
if (attacker.getStamina() < (weapon.template.item_wt / 3f)) {
|
||||
if (attacker.getStamina() < (weapon.template.getItemWt() / 3f)) {
|
||||
//set auto attack job
|
||||
setAutoAttackJob(attacker, slot, delay);
|
||||
return;
|
||||
}
|
||||
}
|
||||
float stam = weapon.template.item_wt / 3f;
|
||||
float stam = weapon.template.getItemWt() / 3f;
|
||||
stam = (stam < 1) ? 1 : stam;
|
||||
attacker.modifyStamina(-(stam), attacker, true);
|
||||
} else
|
||||
@@ -416,7 +419,7 @@ public enum CombatManager {
|
||||
if (((Mob) attacker).isSiege())
|
||||
damageType = mbEnums.DamageType.SIEGE;
|
||||
} else {
|
||||
damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0];
|
||||
damageType = engine.parsers.objects.ItemTemplate.getWeapon(attacker.charItemManager.getEquipped().get(slot).templateID).weapon_damage.get(0).damage_type;
|
||||
}
|
||||
|
||||
//get resists
|
||||
@@ -577,13 +580,14 @@ public enum CombatManager {
|
||||
target.setCombatTarget(attacker);
|
||||
}
|
||||
|
||||
public static int getSwingAnimation(ItemTemplate wb, DeferredPowerJob dpj, mbEnums.EquipSlotType slot) {
|
||||
public static int getSwingAnimation(CObjectTemplate wb, DeferredPowerJob dpj, mbEnums.EquipSlotType slot) {
|
||||
|
||||
//No weapon, return default animation
|
||||
if (wb == null)
|
||||
return 75;
|
||||
|
||||
int token;
|
||||
engine.parsers.objects.ItemTemplate.Weapon weapon = engine.parsers.objects.ItemTemplate.getWeapon(wb.getTemplateId());
|
||||
|
||||
if (dpj != null) {
|
||||
|
||||
@@ -594,47 +598,30 @@ public enum CombatManager {
|
||||
}
|
||||
|
||||
//Item has no equipment slots and should not try to return an animation, return default instead
|
||||
if (wb.item_eq_slots_or == null || wb.item_eq_slots_or.isEmpty()) {
|
||||
if (wb.getItemEqSlotsOr().isEmpty()) {
|
||||
return 75;
|
||||
}
|
||||
|
||||
//declare variables
|
||||
int anim;
|
||||
int random;
|
||||
mbEnums.EquipSlotType hand;
|
||||
ArrayList<int[]> anims;
|
||||
|
||||
//Item can only be equipped in one slot, return animation for that slot
|
||||
if (wb.item_eq_slots_or.size() == 1) {
|
||||
if (wb.item_eq_slots_or.iterator().next().equals(mbEnums.EquipSlotType.RHELD)) {
|
||||
anim = wb.weapon_attack_anim_right.get(0)[0];
|
||||
if (dpj != null) {
|
||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
|
||||
anim = wb.weapon_attack_anim_right.get(random)[0];
|
||||
}
|
||||
} else {
|
||||
anim = wb.weapon_attack_anim_left.get(0)[0];
|
||||
if (dpj != null) {
|
||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
|
||||
anim = wb.weapon_attack_anim_left.get(random)[0];
|
||||
}
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
//Item can only be equipped in one slot, use the animations for that slot
|
||||
if (wb.getItemEqSlotsOr().size() == 1)
|
||||
hand = wb.getItemEqSlotsOr().iterator().next();
|
||||
else
|
||||
hand = slot;
|
||||
|
||||
//Item can be equipped in either hand, and should have animation sets for each hand
|
||||
if (slot.equals(mbEnums.EquipSlotType.RHELD)) {
|
||||
anim = wb.weapon_attack_anim_right.get(0)[0];
|
||||
if (dpj != null) {
|
||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
|
||||
anim = wb.weapon_attack_anim_right.get(random)[0];
|
||||
}
|
||||
} else {
|
||||
anim = wb.weapon_attack_anim_left.get(0)[0];
|
||||
if (dpj != null) {
|
||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
|
||||
anim = wb.weapon_attack_anim_left.get(random)[0];
|
||||
}
|
||||
}
|
||||
return anim;
|
||||
anims = hand.equals(mbEnums.EquipSlotType.RHELD) ? weapon.weapon_attack_anim_right : weapon.weapon_attack_anim_left;
|
||||
|
||||
// Many cache weapons have no swing anims; GUESS: the client falls back to the default too
|
||||
if (anims.isEmpty())
|
||||
return 75;
|
||||
|
||||
if (dpj != null)
|
||||
return anims.get(ThreadLocalRandom.current().nextInt(anims.size()))[0];
|
||||
|
||||
return anims.get(0)[0];
|
||||
}
|
||||
|
||||
public static int getPassiveAnimation(mbEnums.PassiveType passiveType) {
|
||||
@@ -713,7 +700,7 @@ public enum CombatManager {
|
||||
// Mobs use their mobbase rune, players use their race rune.
|
||||
|
||||
int runeID;
|
||||
ItemTemplate rune;
|
||||
RuneTemplate rune;
|
||||
int hand = slot.equals(mbEnums.EquipSlotType.LHELD) ? 2 : 1;
|
||||
|
||||
switch (attacker.getObjectType()) {
|
||||
@@ -727,18 +714,18 @@ public enum CombatManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
rune = ItemTemplate.templates.get(runeID);
|
||||
rune = RuneTemplate._runes.get(runeID);
|
||||
|
||||
if (rune == null || rune.rune_natural_attacks.isEmpty())
|
||||
if (rune == null || rune.rune_naturalattacks.isEmpty())
|
||||
return null;
|
||||
|
||||
for (float[] attack : rune.rune_natural_attacks)
|
||||
for (float[] attack : rune.rune_naturalattacks)
|
||||
if (attack.length > 3 && (int) attack[3] == hand)
|
||||
return attack;
|
||||
|
||||
// No entry for this hand, fall back to the first natural attack
|
||||
|
||||
return rune.rune_natural_attacks.get(0);
|
||||
return rune.rune_naturalattacks.get(0);
|
||||
}
|
||||
|
||||
public static int calculatePetDamage(AbstractCharacter agent) {
|
||||
|
||||
@@ -71,10 +71,13 @@ public enum ConfigManager {
|
||||
MB_WORLD_KEYCLONE_MAX,
|
||||
MB_USE_RUINS,
|
||||
MB_RULESET,
|
||||
MB_STATIC_BUILDINGS,
|
||||
MB_STATIC_RUNEGATES,
|
||||
|
||||
// Mobile AI modifiers
|
||||
MB_AI_CAST_FREQUENCY,
|
||||
MB_AI_AGGRO_RANGE,
|
||||
MB_MINION_SPAWN_TIME,
|
||||
|
||||
//drop rates
|
||||
MB_NORMAL_EXP_RATE,
|
||||
@@ -165,14 +168,6 @@ public enum ConfigManager {
|
||||
|
||||
regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue()));
|
||||
|
||||
Logger.info("Loading WPAK data");
|
||||
|
||||
// *** Needs powermanager collection
|
||||
// defined before activation.
|
||||
// EffectsParser.parseWpakFile();
|
||||
// PowersParser.parseWpakFile();
|
||||
// PowerActionParser.parseWpakFile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,15 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public enum DbManager {
|
||||
DBMANAGER;
|
||||
|
||||
// Static world IDs count down from -2 (-1 means "not found"); runtime negative IDs start below them.
|
||||
public static final int RUNTIME_ID_START = -1_000_000;
|
||||
private static final AtomicInteger lastStaticID = new AtomicInteger(-1);
|
||||
|
||||
public static final dbAccountHandler AccountQueries = new dbAccountHandler();
|
||||
public static final dbBaneHandler BaneQueries = new dbBaneHandler();
|
||||
|
||||
@@ -44,10 +49,8 @@ public enum DbManager {
|
||||
// Omg refactor this out, somebody!
|
||||
public static final dbCSSessionHandler CSSessionQueries = new dbCSSessionHandler();
|
||||
public static final dbEnchantmentHandler EnchantmentQueries = new dbEnchantmentHandler();
|
||||
public static final dbEffectsResourceCostHandler EffectsResourceCostsQueries = new dbEffectsResourceCostHandler();
|
||||
public static final dbGuildHandler GuildQueries = new dbGuildHandler();
|
||||
public static final dbItemHandler ItemQueries = new dbItemHandler();
|
||||
public static final dbKitHandler KitQueries = new dbKitHandler();
|
||||
public static final dbLootHandler LootQueries = new dbLootHandler();
|
||||
public static final dbMenuHandler MenuQueries = new dbMenuHandler();
|
||||
public static final dbMineHandler MineQueries = new dbMineHandler();
|
||||
@@ -57,9 +60,6 @@ public enum DbManager {
|
||||
public static final dbPlayerCharacterHandler PlayerCharacterQueries = new dbPlayerCharacterHandler();
|
||||
public static final dbPromotionClassHandler PromotionQueries = new dbPromotionClassHandler();
|
||||
public static final dbRaceHandler RaceQueries = new dbRaceHandler();
|
||||
public static final dbResistHandler ResistQueries = new dbResistHandler();
|
||||
public static final dbRuneBaseAttributeHandler RuneBaseAttributeQueries = new dbRuneBaseAttributeHandler();
|
||||
public static final dbRuneBaseEffectHandler RuneBaseEffectQueries = new dbRuneBaseEffectHandler();
|
||||
public static final dbRuneBaseHandler RuneBaseQueries = new dbRuneBaseHandler();
|
||||
public static final dbSkillBaseHandler SkillsBaseQueries = new dbSkillBaseHandler();
|
||||
public static final dbSkillReqHandler SkillReqQueries = new dbSkillReqHandler();
|
||||
@@ -69,13 +69,59 @@ public enum DbManager {
|
||||
public static final dbBlueprintHandler BlueprintQueries = new dbBlueprintHandler();
|
||||
public static final dbShrineHandler ShrineQueries = new dbShrineHandler();
|
||||
public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler();
|
||||
public static final dbStaticWorldHandler StaticWorldQueries = new dbStaticWorldHandler();
|
||||
|
||||
public static final dbPowerHandler PowerQueries = new dbPowerHandler();
|
||||
public static final dbPetitionHandler PetitionQueries = new dbPetitionHandler();
|
||||
private static final EnumMap<GameObjectType, ConcurrentHashMap<Integer, AbstractGameObject>> objectCache = new EnumMap<>(GameObjectType.class);
|
||||
public static Hasher hasher;
|
||||
private static HikariDataSource connectionPool = null;
|
||||
|
||||
// Only the static world factories may call this, in the fixed load order (W2); never renumber.
|
||||
// The key names the object from the data files alone (findings §5, manifest format) and must be unique.
|
||||
public static int nextStaticID(GameObjectType objectType, String manifestKey) {
|
||||
|
||||
int staticID = lastStaticID.decrementAndGet();
|
||||
|
||||
if (staticID <= RUNTIME_ID_START)
|
||||
throw new IllegalStateException("Static world ID " + staticID + " reached the runtime ID range at " + RUNTIME_ID_START);
|
||||
|
||||
StaticManifest.addEntry(staticID, objectType, manifestKey);
|
||||
|
||||
return staticID;
|
||||
}
|
||||
|
||||
// W3: static world objects never reach the DB. Logs the refused handler method and its caller.
|
||||
public static boolean refuseStaticWrite(AbstractWorldObject worldObject) {
|
||||
|
||||
StackTraceElement[] stack;
|
||||
String caller;
|
||||
int frame = 1;
|
||||
|
||||
if (worldObject == null || !worldObject.isStaticWorldObject())
|
||||
return false;
|
||||
|
||||
stack = new Throwable().getStackTrace();
|
||||
|
||||
while (frame < stack.length - 1 && stack[frame].getClassName().equals(DbManager.class.getName()))
|
||||
frame++;
|
||||
|
||||
caller = (frame + 1 < stack.length) ? stack[frame + 1].toString() : "unknown";
|
||||
|
||||
Logger.error("Refused DB write for static " + worldObject.getObjectType() + " " + worldObject.getObjectUUID()
|
||||
+ " in " + stack[frame] + " called from " + caller);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean refuseStaticWrite(GameObjectType objectType, long objectUUID) {
|
||||
|
||||
AbstractGameObject gameObject = getFromCache(objectType, (int) objectUUID);
|
||||
|
||||
if (gameObject instanceof AbstractWorldObject)
|
||||
return refuseStaticWrite((AbstractWorldObject) gameObject);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static AbstractGameObject getObject(GameObjectType objectType, int objectUUID) {
|
||||
|
||||
AbstractGameObject outObject = null;
|
||||
|
||||
@@ -101,6 +101,7 @@ public enum DevCmdManager {
|
||||
DevCmdManager.registerDevCmd(new SetAdminRuneCmd());
|
||||
DevCmdManager.registerDevCmd(new SetInvulCmd());
|
||||
DevCmdManager.registerDevCmd(new MakeItemCmd());
|
||||
DevCmdManager.registerDevCmd(new FillCmd());
|
||||
DevCmdManager.registerDevCmd(new SetSubRaceCmd());
|
||||
// Admin
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import engine.mbEnums;
|
||||
import engine.net.client.msg.ItemProductionMsg;
|
||||
import engine.objects.City;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.NPC;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -49,6 +49,9 @@ public enum ForgeManager implements Runnable {
|
||||
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>();
|
||||
|
||||
// Server-only data from static_vendor_items; the client templates have no mod table.
|
||||
public static HashMap<Integer, Integer> vendorModTables = new HashMap<>();
|
||||
|
||||
public static void start() {
|
||||
|
||||
Thread forgeManager;
|
||||
@@ -128,6 +131,11 @@ public enum ForgeManager implements Runnable {
|
||||
if (city == null)
|
||||
return 58; //58: The formula is beyond the means of this facility
|
||||
|
||||
// NPC buildings have no strongbox to pay from, as in vendor buy, repair and train
|
||||
|
||||
if (workOrder.vendor.building.getProtectionState() == mbEnums.ProtectionState.NPC)
|
||||
return 58;
|
||||
|
||||
// Concurrency is rightly managed by same lock as warehouse
|
||||
|
||||
city.transactionLock.writeLock().lock();
|
||||
@@ -222,12 +230,12 @@ public enum ForgeManager implements Runnable {
|
||||
// Calculate production cost for a single run of the workOrder
|
||||
|
||||
HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>();
|
||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID);
|
||||
|
||||
// Add gold and resource costs from template
|
||||
|
||||
production_cost.put(mbEnums.ResourceType.GOLD, template.item_value);
|
||||
production_cost.putAll(template.item_resource_cost);
|
||||
production_cost.put(mbEnums.ResourceType.GOLD, template.getItemValue());
|
||||
production_cost.putAll(template.getItemResourceCosts());
|
||||
|
||||
// Calculate cost of prefix and suffix
|
||||
|
||||
@@ -248,8 +256,8 @@ public enum ForgeManager implements Runnable {
|
||||
|
||||
// Create new virtual item from specified template
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
||||
Item forgedItem = new Item(workOrder.templateID);
|
||||
int modTable = getVendorModTable(workOrder.templateID);
|
||||
|
||||
// forgedItem gets a negative id; a virtual item which is not persisted
|
||||
|
||||
@@ -264,13 +272,13 @@ public enum ForgeManager implements Runnable {
|
||||
|
||||
// Assign a prefix and suffix to this item if random rolled
|
||||
|
||||
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
|
||||
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, template.modTable);
|
||||
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
|
||||
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, modTable);
|
||||
else
|
||||
forgedItem.prefixToken = workOrder.prefixToken;
|
||||
|
||||
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
|
||||
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, template.modTable);
|
||||
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
|
||||
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, modTable);
|
||||
else
|
||||
forgedItem.suffixToken = workOrder.suffixToken;
|
||||
|
||||
@@ -364,6 +372,10 @@ public enum ForgeManager implements Runnable {
|
||||
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
|
||||
}
|
||||
|
||||
public static int getVendorModTable(int templateID) {
|
||||
return vendorModTables.getOrDefault(templateID, 0);
|
||||
}
|
||||
|
||||
public static int calcRandomMod(NPC vendor, mbEnums.ItemModType itemModType, int modTable) {
|
||||
|
||||
// Random prefix or suffix token based on item.template.modtable
|
||||
|
||||
@@ -307,7 +307,7 @@ public enum GroupManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!item.template.item_type.equals(mbEnums.ItemType.GOLD)) //only split goldItem
|
||||
if (!item.template.getItemType().equals(mbEnums.ItemType.GOLD)) //only split goldItem
|
||||
return false;
|
||||
|
||||
Group group = getGroup(pc);
|
||||
|
||||
@@ -16,7 +16,18 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.guild.AcceptInviteToGuildMsg;
|
||||
import engine.net.client.msg.guild.GuildInfoMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.map.GuildSeedParser;
|
||||
import engine.parsers.objects.CZoneProp;
|
||||
import engine.parsers.objects.GuildSeed;
|
||||
import engine.parsers.objects.GuildSeedEntry;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public enum GuildManager {
|
||||
|
||||
@@ -33,6 +44,100 @@ public enum GuildManager {
|
||||
public static final int CREST_RESERVED = 153; //153: Guild crest is reserved
|
||||
public static final int CREST_COLOR_ERROR = 154; //154: All three crest colors cannot be the same
|
||||
|
||||
// NPC guilds by CZONE city_prop_gm_guild / city_prop_gm_nation key (W7)
|
||||
public static final HashMap<Integer, Guild> _npcGuildsByKey = new HashMap<>();
|
||||
public static final HashMap<Integer, Guild> _npcGuildsByNationKey = new HashMap<>();
|
||||
public static final HashSet<Integer> _noGuildKeys = new HashSet<>();
|
||||
public static final HashSet<Integer> _ruinKeys = new HashSet<>();
|
||||
public static final HashMap<Integer, GuildSeedEntry> _npcSeedEntriesByGuildID = new HashMap<>();
|
||||
|
||||
// Static NPC guilds from maps/<map>.guild. Loaded before zones, so they take the first static IDs. False aborts boot.
|
||||
|
||||
public static boolean loadStaticGuilds(int mapID) {
|
||||
|
||||
GuildSeed guildSeed;
|
||||
Guild guild;
|
||||
|
||||
guildSeed = GuildSeedParser.parseGuildSeed(mapID);
|
||||
|
||||
if (guildSeed == null)
|
||||
return false;
|
||||
|
||||
for (GuildSeedEntry seedEntry : guildSeed.guilds) {
|
||||
|
||||
guild = Guild.createStaticGuild(seedEntry);
|
||||
DbManager.addToCache(guild);
|
||||
_npcSeedEntriesByGuildID.put(guild.getObjectUUID(), seedEntry);
|
||||
|
||||
for (int guildKey : seedEntry.guildKeys)
|
||||
if (_npcGuildsByKey.put(guildKey, guild) != null || guildSeed.noGuildKeys.contains(guildKey) || guildSeed.ruinKeys.contains(guildKey)) {
|
||||
Logger.error("Guild seed: guild key " + String.format("%08X", guildKey) + " is used twice");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_npcGuildsByNationKey.put(seedEntry.nationKey, guild) != null) {
|
||||
Logger.error("Guild seed: nation key " + String.format("%08X", seedEntry.nationKey) + " is used twice");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_noGuildKeys.addAll(guildSeed.noGuildKeys);
|
||||
_noGuildKeys.addAll(guildSeed.ruinKeys);
|
||||
_ruinKeys.addAll(guildSeed.ruinKeys);
|
||||
|
||||
Logger.info("NPC guilds: " + guildSeed.guilds.size() + " static, " + _npcGuildsByKey.size() + " guild keys");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Logs each CITY-prop guild key on the map that has no seed entry; known no-guild keys are only counted.
|
||||
|
||||
public static void logMissingGuildKeys() {
|
||||
|
||||
TreeMap<String, TreeSet<String>> missingKeys = new TreeMap<>();
|
||||
ArrayList<CZoneProp> cityProps = new ArrayList<>();
|
||||
int noGuildProps = 0;
|
||||
|
||||
for (Zone zone : ZoneManager.getAllZones()) {
|
||||
|
||||
if (!zone.isStaticWorldObject() || zone.template == null)
|
||||
continue;
|
||||
|
||||
cityProps.clear();
|
||||
collectCityProps(zone.template.zone_prop_info, cityProps);
|
||||
|
||||
for (CZoneProp cityProp : cityProps) {
|
||||
|
||||
if (_npcGuildsByKey.containsKey(cityProp.city_prop_gm_guild))
|
||||
continue;
|
||||
|
||||
if (_noGuildKeys.contains(cityProp.city_prop_gm_guild)) {
|
||||
noGuildProps++;
|
||||
continue;
|
||||
}
|
||||
|
||||
missingKeys.computeIfAbsent(String.format("%08X", cityProp.city_prop_gm_guild), key -> new TreeSet<>())
|
||||
.add(zone.zoneName);
|
||||
}
|
||||
}
|
||||
|
||||
for (String guildKey : missingKeys.keySet())
|
||||
Logger.warn("CITY prop guild key " + guildKey + " has no guild seed entry; zones: " + missingKeys.get(guildKey));
|
||||
|
||||
Logger.info("CITY props: " + noGuildProps + " with no guild, " + missingKeys.size() + " guild keys missing from the seed");
|
||||
}
|
||||
|
||||
private static void collectCityProps(ArrayList<CZoneProp> props, ArrayList<CZoneProp> cityProps) {
|
||||
|
||||
for (CZoneProp prop : props) {
|
||||
|
||||
if (prop.prop_type == mbEnums.ZonePropType.CITY)
|
||||
cityProps.add(prop);
|
||||
|
||||
collectCityProps(prop.prop_content_props, cityProps);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean joinGuild(PlayerCharacter pc, Guild guild, GuildHistoryType historyType) {
|
||||
return joinGuild(pc, guild, 0, historyType);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package engine.gameManager;
|
||||
|
||||
import engine.mbEnums;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -19,68 +20,49 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
public enum ItemManager {
|
||||
ITEMMANAGER;
|
||||
|
||||
public static final AtomicInteger lastNegativeID = new AtomicInteger(0);
|
||||
// Shared by every runtime object with a negative ID: loot, forged and contract items, pets and minions.
|
||||
public static final AtomicInteger lastNegativeID = new AtomicInteger(DbManager.RUNTIME_ID_START);
|
||||
|
||||
// restrict true: the set is a blacklist; false: a whitelist. An empty set allows everyone.
|
||||
|
||||
public static Boolean ValidRace(Item item, mbEnums.MonsterType race) {
|
||||
|
||||
if (item.template.item_race_req.isEmpty() && item.template.item_race_res.isEmpty())
|
||||
EnumSet<mbEnums.MonsterType> races = item.template.getItemRaceReq();
|
||||
boolean restrict = item.template.getItemRaceReqRestrict();
|
||||
|
||||
if (races.isEmpty())
|
||||
return true;
|
||||
|
||||
if (item.template.item_race_req.isEmpty() == false)
|
||||
if (item.template.item_race_req.contains(race))
|
||||
return true;
|
||||
|
||||
if (item.template.item_race_res.isEmpty() == false)
|
||||
if (item.template.item_race_res.contains(race) == false)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return races.contains(race) != restrict;
|
||||
}
|
||||
|
||||
public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) {
|
||||
|
||||
// Early exit if no entry
|
||||
EnumSet<mbEnums.ClassType> classes = item.template.getItemClassReq();
|
||||
boolean restrict = item.template.getItemClassReqRestrict();
|
||||
boolean listed;
|
||||
|
||||
if (item.template.item_class_req.isEmpty() && item.template.item_class_res.isEmpty())
|
||||
if (classes.isEmpty())
|
||||
return true;
|
||||
|
||||
if (item.template.item_class_req.isEmpty() == false)
|
||||
if (item.template.item_class_req.contains(base) || item.template.item_class_req.contains(profession))
|
||||
return true;
|
||||
listed = classes.contains(base) || classes.contains(profession);
|
||||
|
||||
if (item.template.item_class_res.isEmpty() == false)
|
||||
if (item.template.item_class_res.contains(base) == false && item.template.item_class_res.contains(profession) == false)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return listed != restrict;
|
||||
}
|
||||
|
||||
public static Boolean ValidDiscipline(Item item, EnumSet<mbEnums.DisciplineType> discs) {
|
||||
|
||||
// Early exit if no entry
|
||||
EnumSet<mbEnums.DisciplineType> disciplines = item.template.getItemDiscReq();
|
||||
boolean restrict = item.template.getItemDiscReqRestrict();
|
||||
EnumSet<mbEnums.DisciplineType> workSet;
|
||||
|
||||
if (item.template.item_disc_req.isEmpty() && item.template.item_disc_res.isEmpty())
|
||||
if (disciplines.isEmpty())
|
||||
return true;
|
||||
|
||||
EnumSet<mbEnums.DisciplineType> workSet = EnumSet.copyOf(discs);
|
||||
workSet = EnumSet.copyOf(discs);
|
||||
workSet.retainAll(disciplines);
|
||||
|
||||
if (item.template.item_disc_req.isEmpty() == false) {
|
||||
|
||||
workSet.retainAll(item.template.item_disc_req);
|
||||
|
||||
if (workSet.isEmpty() == false)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.template.item_disc_res.isEmpty() == false) {
|
||||
|
||||
workSet.retainAll(item.template.item_disc_res);
|
||||
|
||||
if (workSet.isEmpty() == false)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return workSet.isEmpty() == restrict;
|
||||
}
|
||||
|
||||
public static Boolean canCharacterEquip(Item item, AbstractCharacter character) {
|
||||
@@ -91,12 +73,12 @@ public enum ItemManager {
|
||||
|
||||
CharacterSkill characterSkill;
|
||||
|
||||
if (item.template.item_skill_required.isEmpty())
|
||||
if (item.template.getItemSkillReq().isEmpty())
|
||||
return true;
|
||||
|
||||
for (String skillRequired : item.template.item_skill_required.keySet()) {
|
||||
for (String skillRequired : item.template.getItemSkillReq().keySet()) {
|
||||
|
||||
int required_value = item.template.item_skill_required.get(skillRequired);
|
||||
int required_value = item.template.getItemSkillReq().get(skillRequired);
|
||||
characterSkill = skills.get(skillRequired);
|
||||
|
||||
if (characterSkill == null)
|
||||
@@ -112,31 +94,31 @@ public enum ItemManager {
|
||||
|
||||
public static boolean isTwoHanded(Item item) {
|
||||
|
||||
if (!item.template.item_type.equals(mbEnums.ItemType.WEAPON))
|
||||
if (!item.template.getItemType().equals(mbEnums.ItemType.WEAPON))
|
||||
return false;
|
||||
|
||||
return item.template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
return item.template.getItemEqSlotsAnd().containsAll(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
}
|
||||
|
||||
public static boolean isTwoHanded(ItemTemplate template) {
|
||||
public static boolean isTwoHanded(CObjectTemplate template) {
|
||||
|
||||
if (!template.item_type.equals(mbEnums.ItemType.WEAPON))
|
||||
if (!template.getItemType().equals(mbEnums.ItemType.WEAPON))
|
||||
return false;
|
||||
|
||||
return template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
return template.getItemEqSlotsAnd().containsAll(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
}
|
||||
|
||||
public static boolean isShield(Item item) {
|
||||
|
||||
if (item.template.item_skill_required.containsKey("Block"))
|
||||
if (item.template.getItemSkillReq().containsKey("Block"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isShield(ItemTemplate template) {
|
||||
public static boolean isShield(CObjectTemplate template) {
|
||||
|
||||
if (template.item_skill_required.containsKey("Block"))
|
||||
if (template.getItemSkillReq().containsKey("Block"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -150,7 +132,7 @@ public enum ItemManager {
|
||||
return false;
|
||||
//Item not valid for slot
|
||||
|
||||
if (item.template.item_eq_slots_or.contains(slot) == false)
|
||||
if (item.template.getItemEqSlotsOr().contains(slot) == false)
|
||||
return false;
|
||||
|
||||
// Slot is taken
|
||||
@@ -165,7 +147,7 @@ public enum ItemManager {
|
||||
(slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null)))
|
||||
return false;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.WEAPON))
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.WEAPON))
|
||||
if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false)
|
||||
return false;
|
||||
|
||||
@@ -197,7 +179,7 @@ public enum ItemManager {
|
||||
|
||||
//players can't wear 0 value items.
|
||||
|
||||
return item.template.item_value != 0 || Kit.IsNoobGear(item.templateID);
|
||||
return item.template.getItemValue() != 0 || Kit.IsNoobGear(item.templateID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import engine.mbEnums;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.chat.ChatSystemMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -91,8 +92,8 @@ public enum LootManager {
|
||||
//lastly, check mobs inventory for godly or disc runes to send a server announcement
|
||||
for (Item item : mob.getInventory()) {
|
||||
|
||||
if ((item.templateID > 2499 && item.templateID <= 3050) || item.template.item_base_name.toLowerCase().contains("of the gods")) {
|
||||
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + item.template.item_base_name + ". Are you tough enough to take it?");
|
||||
if ((item.templateID > 2499 && item.templateID <= 3050) || item.template.getItemBaseName().toLowerCase().contains("of the gods")) {
|
||||
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + item.template.getItemBaseName() + ". Are you tough enough to take it?");
|
||||
chatMsg.setMessageType(10);
|
||||
chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID());
|
||||
DispatchManager.dispatchMsgToAll(chatMsg);
|
||||
@@ -179,12 +180,12 @@ public enum LootManager {
|
||||
if (itemUUID == 0)
|
||||
return null;
|
||||
|
||||
if (ItemTemplate.templates.get(itemUUID).item_type.equals(mbEnums.ItemType.RESOURCE)) {
|
||||
if (CObjectTemplate.lookup(itemUUID).getItemType().equals(mbEnums.ItemType.RESOURCE)) {
|
||||
int amount = ThreadLocalRandom.current().nextInt(tableRow.minSpawn, tableRow.maxSpawn + 1);
|
||||
return new MobLoot(mob, ItemTemplate.templates.get(itemUUID), amount, false);
|
||||
return new MobLoot(mob, CObjectTemplate.lookup(itemUUID), amount, false);
|
||||
}
|
||||
|
||||
outItem = new MobLoot(mob, ItemTemplate.templates.get(itemUUID), false);
|
||||
outItem = new MobLoot(mob, CObjectTemplate.lookup(itemUUID), false);
|
||||
|
||||
if (selectedRow.pModTable != 0)
|
||||
try {
|
||||
@@ -374,7 +375,7 @@ public enum LootManager {
|
||||
if (chanceRoll > bse.dropChance)
|
||||
return;
|
||||
|
||||
MobLoot lootItem = new MobLoot(mob, ItemTemplate.templates.get(bse.templateID), true);
|
||||
MobLoot lootItem = new MobLoot(mob, CObjectTemplate.lookup(bse.templateID), true);
|
||||
|
||||
if (lootItem != null)
|
||||
mob.charItemManager.addItemToInventory(lootItem);
|
||||
@@ -422,14 +423,14 @@ public enum LootManager {
|
||||
|
||||
//create the item from the table, quantity is always 1
|
||||
|
||||
MobLoot winnings = new MobLoot(playerCharacter, ItemTemplate.templates.get(selectedItem.templateID), 1, false);
|
||||
MobLoot winnings = new MobLoot(playerCharacter, CObjectTemplate.lookup(selectedItem.templateID), 1, false);
|
||||
|
||||
if (winnings == null)
|
||||
return;
|
||||
|
||||
//early exit if the inventory of the player will not old the item
|
||||
|
||||
if (itemMan.hasRoomInventory(winnings.template.item_wt) == false) {
|
||||
if (itemMan.hasRoomInventory(winnings.template.getItemWt()) == false) {
|
||||
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ public enum MovementManager {
|
||||
|
||||
// if inside a building, convert both locations from the building local reference frame to the world reference frame
|
||||
|
||||
if (msg.getInBuildingUUID() > 0) {
|
||||
if (msg.getInBuildingUUID() != 0) {
|
||||
Building building = BuildingManager.getBuildingFromCache(msg.getInBuildingUUID());
|
||||
if (building != null) {
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ package engine.gameManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.loot.WorkOrder;
|
||||
import engine.math.Quaternion;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums;
|
||||
import engine.net.Dispatch;
|
||||
@@ -19,19 +18,19 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.PetMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.RuneSkillAdjustEntry;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static engine.math.FastMath.acos;
|
||||
|
||||
public enum NPCManager {
|
||||
|
||||
NPC_MANAGER;
|
||||
@@ -225,11 +224,12 @@ public enum NPCManager {
|
||||
|
||||
abstractCharacter.loc = new Vector3fImmutable(abstractCharacter.bindLoc);
|
||||
|
||||
// Rotate NPC rotation by the building's rotation
|
||||
// Rotate NPC rotation by the building's rotation.
|
||||
// Kept for wire parity: the product's sin θ/2 is read back as cos θ/2, so the yaw sent is not own + building.
|
||||
|
||||
Quaternion slotRotation = new Quaternion().fromAngles(0, acos(abstractCharacter.getRot().y) * 2, 0);
|
||||
Quaternion slotRotation = new Quaternion().fromAngles(0, abstractCharacter.getRotation().getYaw(), 0);
|
||||
slotRotation = slotRotation.mult(abstractCharacter.building.getBounds().getQuaternion());
|
||||
abstractCharacter.setRot(new Vector3f(0, slotRotation.y, 0));
|
||||
abstractCharacter.setRotation(Quaternion.fromYaw((float) Math.acos(slotRotation.y) * 2));
|
||||
|
||||
// Configure region and floor/level for this NPC
|
||||
|
||||
@@ -315,26 +315,26 @@ public enum NPCManager {
|
||||
//has main hand weapon
|
||||
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD);
|
||||
|
||||
if (weapon.template.item_primary_attr.equals(mbEnums.AttributeType.Strength))
|
||||
if (engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == mbEnums.AttributeType.Strength)
|
||||
primaryStat = guard.getStatStrCurrent();
|
||||
else
|
||||
primaryStat = guard.getStatDexCurrent();
|
||||
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = weapon.template.item_weapon_wepspeed;
|
||||
guard.rangeHandOne = weapon.template.item_weapon_max_range;
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed;
|
||||
guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range;
|
||||
} else if (guard.charItemManager.equipped.containsKey(mbEnums.EquipSlotType.LHELD) && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template)) {
|
||||
//has off hand weapon
|
||||
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD);
|
||||
if (weapon.template.item_primary_attr.equals(mbEnums.AttributeType.Strength))
|
||||
if (engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == mbEnums.AttributeType.Strength)
|
||||
primaryStat = guard.getStatStrCurrent();
|
||||
else
|
||||
primaryStat = guard.getStatDexCurrent();
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = weapon.template.item_weapon_wepspeed;
|
||||
guard.rangeHandOne = weapon.template.item_weapon_max_range;
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed;
|
||||
guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range;
|
||||
} else {
|
||||
primaryStat = guard.getStatStrCurrent();
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
|
||||
@@ -352,8 +352,8 @@ public enum NPCManager {
|
||||
int baseDef = guard.mobBase.getDefenseRating();
|
||||
int armorDefense = 0;
|
||||
for (Item equipped : guard.charItemManager.equipped.values())
|
||||
if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template))
|
||||
armorDefense += equipped.template.item_defense_rating;
|
||||
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template))
|
||||
armorDefense += engine.parsers.objects.ItemTemplate._items.get(equipped.templateID).item_defense_rating;
|
||||
guard.defenseRating = dexterity + baseDef + armorDefense;
|
||||
}
|
||||
|
||||
@@ -361,9 +361,9 @@ public enum NPCManager {
|
||||
int strength = guard.getStatStrCurrent();
|
||||
int baseAtr = guard.mobBase.getAttackRating();
|
||||
if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD) != null)
|
||||
guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.item_skill_required.values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.item_skill_required.values().toArray()[0] * 3));
|
||||
guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.getItemSkillReq().values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.getItemSkillReq().values().toArray()[0] * 3));
|
||||
else if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD) != null && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template))
|
||||
guard.atrHandTwo = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.item_skill_required.values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.item_skill_required.values().toArray()[0] * 3));
|
||||
guard.atrHandTwo = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.getItemSkillReq().values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.getItemSkillReq().values().toArray()[0] * 3));
|
||||
else
|
||||
guard.atrHandOne = baseAtr;
|
||||
}
|
||||
@@ -434,28 +434,63 @@ public enum NPCManager {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mob.isNecroPet())
|
||||
applyNecroPetStats(mob);
|
||||
}
|
||||
|
||||
// No client data grants NECROPETSTATS, yet NEC-018 and DRU-066 require it on the target; the server adds it to necro pets
|
||||
private static void applyNecroPetStats(Mob mob) {
|
||||
|
||||
EffectsBase necroPetStats = PowersManager.getEffectByIDString("NECROPETSTATS");
|
||||
String effectKey;
|
||||
Effect currentEffect;
|
||||
int rank = -1;
|
||||
|
||||
if (necroPetStats == null) {
|
||||
Logger.error("NECROPETSTATS effect not loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
// GUESS: rank follows the pet's own level ladder (PET_NECRO / PET_NECRO_HARDHIT, from reqLvl 9), as the old DB rows did
|
||||
for (MobBaseEffects mbe : mob.mobBase.effectsList)
|
||||
if (mbe.getReqLvl() > 0 && mbe.getReqLvl() <= (int) mob.level)
|
||||
rank = Math.max(rank, mbe.getRank());
|
||||
|
||||
if (rank < 0)
|
||||
return;
|
||||
|
||||
effectKey = Integer.toString(necroPetStats.getUUID());
|
||||
currentEffect = mob.effects.get(effectKey);
|
||||
|
||||
if (currentEffect != null) {
|
||||
|
||||
if (currentEffect.getTrains() >= rank)
|
||||
return;
|
||||
|
||||
currentEffect.cancelJob();
|
||||
}
|
||||
|
||||
mob.addEffectNoTimer(effectKey, necroPetStats, rank, true);
|
||||
}
|
||||
|
||||
public static void applyEquipmentResists(Mob mob) {
|
||||
|
||||
EnumMap<mbEnums.DamageType, Float> armorResists;
|
||||
|
||||
if (mob.charItemManager.equipped.isEmpty())
|
||||
return;
|
||||
|
||||
for (Item equipped : mob.charItemManager.equipped.values()) {
|
||||
if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR)) {
|
||||
mob.resists.setResist(mbEnums.DamageType.SLASHING, mob.resists.getResist(mbEnums.DamageType.SLASHING, 0) + equipped.template.combat_attack_resist.get("SLASHING"));
|
||||
mob.resists.setResist(mbEnums.DamageType.CRUSHING, mob.resists.getResist(mbEnums.DamageType.CRUSHING, 0) + equipped.template.combat_attack_resist.get("CRUSHING"));
|
||||
mob.resists.setResist(mbEnums.DamageType.PIERCING, mob.resists.getResist(mbEnums.DamageType.PIERCING, 0) + equipped.template.combat_attack_resist.get("PIERCING"));
|
||||
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR)) {
|
||||
armorResists = equipped.template.getCombatAttackResist();
|
||||
mob.resists.setResist(mbEnums.DamageType.SLASHING, mob.resists.getResist(mbEnums.DamageType.SLASHING, 0) + armorResists.getOrDefault(mbEnums.DamageType.SLASHING, 0f));
|
||||
mob.resists.setResist(mbEnums.DamageType.CRUSHING, mob.resists.getResist(mbEnums.DamageType.CRUSHING, 0) + armorResists.getOrDefault(mbEnums.DamageType.CRUSHING, 0f));
|
||||
mob.resists.setResist(mbEnums.DamageType.PIERCING, mob.resists.getResist(mbEnums.DamageType.PIERCING, 0) + armorResists.getOrDefault(mbEnums.DamageType.PIERCING, 0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void applyMobbaseSkill(Mob mob) {
|
||||
SkillsBase baseSkill = DbManager.SkillsBaseQueries.GET_BASE_BY_TOKEN(mob.mobBase.getMobBaseStats().getBaseSkill());
|
||||
if (baseSkill != null)
|
||||
mob.getSkills().put(baseSkill.getName(), new CharacterSkill(baseSkill, mob, mob.mobBase.getMobBaseStats().getBaseSkillAmount()));
|
||||
}
|
||||
|
||||
public static void applyRuneSkills(Mob mob, int runeID) {
|
||||
//load mob skill adjustments from mobbase rune
|
||||
if (PowersManager._allRuneSkillAdjusts.containsKey(runeID))
|
||||
@@ -466,7 +501,7 @@ public enum NPCManager {
|
||||
if (skillBase == null)
|
||||
continue;
|
||||
if (entry.level <= mob.level)
|
||||
if (mob.skills.containsKey(entry.name) == false)
|
||||
if (mob.skills.containsKey(entry.skill_type) == false)
|
||||
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
|
||||
else
|
||||
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
|
||||
@@ -480,6 +515,11 @@ public enum NPCManager {
|
||||
npc.runes.add(shopkeeper);
|
||||
if (NPCManager._runeSetMap.containsKey(npc.runeSetID)) {
|
||||
for (int runeID : _runeSetMap.get(npc.runeSetID)) {
|
||||
|
||||
// Shopkeeper is already applied above and most rune sets repeat it
|
||||
if (runeID == 252620)
|
||||
continue;
|
||||
|
||||
RuneBase rb = RuneBase.getRuneBase(runeID);
|
||||
if (rb != null) {
|
||||
CharacterRune toApply = new CharacterRune(rb, npc.getObjectUUID());
|
||||
@@ -536,14 +576,14 @@ public enum NPCManager {
|
||||
|
||||
public static long calcRollingDuration(NPC vendor, int templateID) {
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(templateID);
|
||||
float rollingDuration;
|
||||
|
||||
if (template == null)
|
||||
return 0;
|
||||
|
||||
if (template.item_bane_rank > 0)
|
||||
return (long) (template.item_bane_rank * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
|
||||
if (template.getItemBaneRank() > 0)
|
||||
return (long) (template.getItemBaneRank() * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
|
||||
|
||||
if (vendor.building == null)
|
||||
return 600;
|
||||
|
||||
@@ -10,9 +10,6 @@ package engine.gameManager;
|
||||
|
||||
import engine.InterestManagement.Terrain;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.handlers.dbEffectsBaseHandler;
|
||||
import engine.db.handlers.dbPowerHandler;
|
||||
import engine.db.handlers.dbSkillReqHandler;
|
||||
import engine.job.AbstractJob;
|
||||
import engine.job.AbstractScheduleJob;
|
||||
import engine.job.JobContainer;
|
||||
@@ -28,8 +25,12 @@ import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.wpak.EffectTemplate;
|
||||
import engine.parsers.objects.wpak.PowActionCostTemplate;
|
||||
import engine.parsers.objects.wpak.PowerActionTemplate;
|
||||
import engine.parsers.objects.wpak.PowerTemplate;
|
||||
import engine.powers.*;
|
||||
import engine.powers.poweractions.AbstractPowerAction;
|
||||
import engine.powers.poweractions.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -37,6 +38,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@@ -53,7 +55,6 @@ public enum PowersManager {
|
||||
public static HashMap<String, AbstractPowerAction> powerActionsByIDString = new HashMap<>();
|
||||
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>();
|
||||
public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>();
|
||||
public static HashMap<String, Integer> AnimationOverrides = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers;
|
||||
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts;
|
||||
public static HashMap<String, HashMap<ResourceType, Integer>> _effect_costMaps = new HashMap<>();
|
||||
@@ -90,16 +91,200 @@ public enum PowersManager {
|
||||
return PowersManager.effectsBaseByToken.get(token);
|
||||
}
|
||||
|
||||
// This pre-loads only PowersBase for login
|
||||
public static void InitializeLoginPowers() {
|
||||
public static void loadEffectCostMaps() {
|
||||
|
||||
// get all PowersBase
|
||||
ArrayList<PowersBase> pbList = dbSkillReqHandler.getAllPowersBase();
|
||||
for (PowActionCostTemplate costTemplate : PowActionCostTemplate._costs.values())
|
||||
PowersManager._effect_costMaps.put(costTemplate.id, new HashMap<>(costTemplate.costs));
|
||||
|
||||
for (PowersBase pb : pbList) {
|
||||
if (pb.getToken() != 0)
|
||||
PowersManager.powersBaseByToken.put(pb.getToken(), pb);
|
||||
Logger.info("Loaded " + PowersManager._effect_costMaps.size() + " effect cost maps from PowActionCostInfo.cfg");
|
||||
}
|
||||
|
||||
// Effects.cfg in file order, then the ApplyEffect/ApplyEffects/Invis actions with no Effects.cfg block
|
||||
private static void loadEffects() {
|
||||
|
||||
int effectID = 0;
|
||||
int actionKeyCount = 0;
|
||||
PowerActionTemplate powerActionTemplate;
|
||||
|
||||
for (EffectTemplate effectTemplate : EffectTemplate._effects.values())
|
||||
addEffect(new EffectsBase(effectTemplate, ++effectID));
|
||||
|
||||
for (String actionID : new TreeSet<>(PowerActionTemplate._powerActions.keySet())) {
|
||||
|
||||
if (EffectTemplate._effects.containsKey(actionID))
|
||||
continue;
|
||||
|
||||
powerActionTemplate = PowerActionTemplate._powerActions.get(actionID);
|
||||
|
||||
switch (powerActionTemplate.action_type) {
|
||||
case ApplyEffect:
|
||||
case ApplyEffects:
|
||||
case Invis:
|
||||
addEffect(new EffectsBase(powerActionTemplate, ++effectID));
|
||||
actionKeyCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + EffectTemplate._effects.size() + " effects from Effects.cfg and "
|
||||
+ actionKeyCount + " effect keys from PowerActions.cfg");
|
||||
}
|
||||
|
||||
// PowerActions.cfg in id order; ids 1..n, OPENGATE keeps 5000
|
||||
private static void loadPowerActions() {
|
||||
|
||||
int powerActionID = 0;
|
||||
PowerActionTemplate powerActionTemplate;
|
||||
AbstractPowerAction powerAction;
|
||||
AbstractPowerAction openGateAction;
|
||||
|
||||
for (String actionID : new TreeSet<>(PowerActionTemplate._powerActions.keySet())) {
|
||||
|
||||
powerActionTemplate = PowerActionTemplate._powerActions.get(actionID);
|
||||
powerAction = buildPowerAction(powerActionTemplate, ++powerActionID);
|
||||
|
||||
if (powerAction == null) {
|
||||
Logger.error("Power action " + actionID + " has unsupported type " + powerActionTemplate.action_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
PowersManager.ActionTokenByIDString.put(actionID, DbManager.hasher.SBStringHash(actionID));
|
||||
PowersManager.powerActionsByIDString.put(actionID, powerAction);
|
||||
PowersManager.powerActionsByID.put(powerAction.getUUID(), powerAction);
|
||||
}
|
||||
|
||||
openGateAction = new OpenGatePowerAction(5000, "OPENGATE", "OpenGate", false);
|
||||
PowersManager.powerActionsByIDString.put("OPENGATE", openGateAction);
|
||||
PowersManager.powerActionsByID.put(openGateAction.getUUID(), openGateAction);
|
||||
|
||||
Logger.info("Loaded " + PowersManager.powerActionsByIDString.size() + " power actions from PowerActions.cfg (incl. OPENGATE)");
|
||||
}
|
||||
|
||||
private static AbstractPowerAction buildPowerAction(PowerActionTemplate powerActionTemplate, int id) {
|
||||
|
||||
HashMap<String, EffectsBase> effects = PowersManager.effectsBaseByIDString;
|
||||
|
||||
switch (powerActionTemplate.action_type) {
|
||||
case ApplyEffect:
|
||||
return new ApplyEffectPowerAction(powerActionTemplate, id, effects);
|
||||
case ApplyEffects:
|
||||
return new ApplyEffectsPowerAction(powerActionTemplate, id, effects);
|
||||
case Block:
|
||||
return new BlockPowerAction(powerActionTemplate, id);
|
||||
case Charm:
|
||||
// FEAR and CONFUSION Charm actions stay no-ops, as when the DB typed them Confusion
|
||||
if (powerActionTemplate.effect_ids.get(0).equals("CHARM"))
|
||||
return new CharmPowerAction(powerActionTemplate, id);
|
||||
return new ConfusionPowerAction(powerActionTemplate, id);
|
||||
case ClaimMine:
|
||||
return new ClaimMinePowerAction(powerActionTemplate, id);
|
||||
case ClearAggro:
|
||||
return new ClearAggroPowerAction(powerActionTemplate, id);
|
||||
case ClearNearbyAggro:
|
||||
return new ClearNearbyAggroPowerAction(powerActionTemplate, id);
|
||||
case Confusion:
|
||||
return new ConfusionPowerAction(powerActionTemplate, id);
|
||||
case CreateMob:
|
||||
return new CreateMobPowerAction(powerActionTemplate, id);
|
||||
case DamageOverTime:
|
||||
return new DamageOverTimePowerAction(powerActionTemplate, id, effects);
|
||||
case DeferredPower:
|
||||
return new DeferredPowerPowerAction(powerActionTemplate, id, effects);
|
||||
case DirectDamage:
|
||||
return new DirectDamagePowerAction(powerActionTemplate, id, effects);
|
||||
case Invis:
|
||||
return new InvisPowerAction(powerActionTemplate, id, effects);
|
||||
case MobRecall:
|
||||
return new MobRecallPowerAction(powerActionTemplate, id);
|
||||
case Peek:
|
||||
return new PeekPowerAction(powerActionTemplate, id);
|
||||
case Recall:
|
||||
return new RecallPowerAction(powerActionTemplate, id);
|
||||
case RemoveEffect:
|
||||
return new RemoveEffectPowerAction(powerActionTemplate, id);
|
||||
case Resurrect:
|
||||
return new ResurrectPowerAction(powerActionTemplate, id);
|
||||
case RunegateTeleport:
|
||||
return new RunegateTeleportPowerAction(powerActionTemplate, id);
|
||||
case SetItemFlag:
|
||||
return new SetItemFlagPowerAction(powerActionTemplate, id);
|
||||
case SimpleDamage:
|
||||
return new SimpleDamagePowerAction(powerActionTemplate, id);
|
||||
case SpireDisable:
|
||||
return new SpireDisablePowerAction(powerActionTemplate, id);
|
||||
case Steal:
|
||||
return new StealPowerAction(powerActionTemplate, id);
|
||||
case Summon:
|
||||
return new SummonPowerAction(powerActionTemplate, id);
|
||||
case Teleport:
|
||||
return new TeleportPowerAction(powerActionTemplate, id);
|
||||
case Track:
|
||||
return new TrackPowerAction(powerActionTemplate, id, effects);
|
||||
case TransferStat:
|
||||
return new TransferStatPowerAction(powerActionTemplate, id, effects);
|
||||
case TransferStatOT:
|
||||
return new TransferStatOTPowerAction(powerActionTemplate, id, effects);
|
||||
case Transform:
|
||||
return new TransformPowerAction(powerActionTemplate, id, effects);
|
||||
case TreeChoke:
|
||||
return new TreeChokePowerAction(powerActionTemplate, id);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void addEffect(EffectsBase effectsBase) {
|
||||
PowersManager.effectsBaseByToken.put(effectsBase.getToken(), effectsBase);
|
||||
PowersManager.effectsBaseByIDString.put(effectsBase.getIDString(), effectsBase);
|
||||
}
|
||||
|
||||
// Powers.cfg in file order, ids 1..n (the old static_power_powerbase IDs)
|
||||
private static void loadPowers() {
|
||||
|
||||
int powerID = 0;
|
||||
PowersBase powersBase;
|
||||
|
||||
for (PowerTemplate powerTemplate : PowerTemplate._powers.values()) {
|
||||
powersBase = new PowersBase(powerTemplate, ++powerID);
|
||||
PowersManager.powersBaseByIDString.put(powersBase.getIDString(), powersBase);
|
||||
PowersManager.powersBaseByToken.put(powersBase.getToken(), powersBase);
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + PowersManager.powersBaseByIDString.size() + " powers from Powers.cfg");
|
||||
}
|
||||
|
||||
// ACTION= lines in Powers.cfg order, ids 1..n (offset in ActionsBase), then the OPENGATE actions
|
||||
private static void loadActionLists() {
|
||||
|
||||
int actionID = 0;
|
||||
PowersBase powersBase;
|
||||
AbstractPowerAction powerAction;
|
||||
|
||||
for (PowerTemplate powerTemplate : PowerTemplate._powers.values()) {
|
||||
|
||||
powersBase = PowersManager.powersBaseByIDString.get(powerTemplate.power_id);
|
||||
|
||||
for (PowerTemplate.ActionEntry actionEntry : powerTemplate.actions) {
|
||||
|
||||
powerAction = PowersManager.powerActionsByIDString.get(actionEntry.action_id);
|
||||
|
||||
if (powerAction == null) {
|
||||
Logger.error("Power " + powerTemplate.power_id + " lists unknown action " + actionEntry.action_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
powersBase.getActions().add(new ActionsBase(actionEntry, powerTemplate.power_id, ++actionID, powerAction));
|
||||
}
|
||||
}
|
||||
|
||||
ActionsBase.addOpenGateActions(PowersManager.powersBaseByIDString);
|
||||
|
||||
Logger.info("Loaded " + actionID + " power action lines from Powers.cfg");
|
||||
}
|
||||
|
||||
// The login server needs only the token map
|
||||
public static void InitializeLoginPowers() {
|
||||
loadPowers();
|
||||
}
|
||||
|
||||
public static ArrayList<RunePowerEntry> getPowersForRune(int rune_id) {
|
||||
@@ -115,48 +300,13 @@ public enum PowersManager {
|
||||
// This pre-loads all powers and effects
|
||||
public static void InitializePowers() {
|
||||
|
||||
// Add EffectsBase
|
||||
ArrayList<EffectsBase> ebList = dbEffectsBaseHandler.getAllEffectsBase();
|
||||
loadEffects();
|
||||
|
||||
for (EffectsBase eb : ebList) {
|
||||
PowersManager.effectsBaseByToken.put(eb.getToken(), eb);
|
||||
PowersManager.effectsBaseByIDString.put(eb.getIDString(), eb);
|
||||
loadPowerActions();
|
||||
|
||||
}
|
||||
|
||||
// Add Fail Conditions
|
||||
EffectsBase.getFailConditions(PowersManager.effectsBaseByIDString);
|
||||
|
||||
// Add Modifiers to Effects
|
||||
dbEffectsBaseHandler.cacheAllEffectModifiers();
|
||||
|
||||
// Add Source Types to Effects
|
||||
dbPowerHandler.addAllSourceTypes();
|
||||
dbPowerHandler.addAllAnimationOverrides();
|
||||
|
||||
// Add PowerActions
|
||||
AbstractPowerAction.getAllPowerActions(PowersManager.powerActionsByIDString, PowersManager.powerActionsByID, PowersManager.effectsBaseByIDString);
|
||||
|
||||
// Load valid Item Flags
|
||||
// AbstractPowerAction.loadValidItemFlags(PowersManager.powerActionsByIDString);
|
||||
|
||||
// get all PowersBase
|
||||
ArrayList<PowersBase> pbList = dbSkillReqHandler.getAllPowersBase();
|
||||
for (PowersBase pb : pbList) {
|
||||
if (pb.getToken() != 0) {
|
||||
PowersManager.powersBaseByIDString.put(pb.getIDString(), pb);
|
||||
PowersManager.powersBaseByToken.put(pb.getToken(), pb);
|
||||
}
|
||||
}
|
||||
|
||||
// Add Power Prereqs
|
||||
PowerPrereq.getAllPowerPrereqs(PowersManager.powersBaseByIDString);
|
||||
// Add Fail Conditions
|
||||
dbSkillReqHandler.getFailConditions(PowersManager.powersBaseByIDString);
|
||||
// Add Actions Base
|
||||
ActionsBase.getActionsBase(PowersManager.powersBaseByIDString,
|
||||
PowersManager.powerActionsByIDString);
|
||||
loadPowers();
|
||||
|
||||
loadActionLists();
|
||||
}
|
||||
|
||||
public static EffectsBase setEffectToken(int ID, int token) {
|
||||
@@ -1255,6 +1405,27 @@ public enum PowersManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
// MONSTERTYPERESTRICTS: mobs use their race rune's monster type, players their RaceType's
|
||||
private static boolean isRestrictedMonsterType(AbstractWorldObject target, PowersBase pb) {
|
||||
|
||||
MonsterType monsterType = null;
|
||||
PlayerCharacter player;
|
||||
|
||||
if (target == null || pb.monsterTypeRestrictions.isEmpty())
|
||||
return false;
|
||||
|
||||
if (target.getObjectType() == GameObjectType.Mob && ((Mob) target).getMobBase() != null)
|
||||
monsterType = ((Mob) target).getMobBase().monsterType;
|
||||
else if (target.getObjectType() == GameObjectType.PlayerCharacter) {
|
||||
player = (PlayerCharacter) target;
|
||||
|
||||
if (player.race != null && player.race.getRaceType() != null)
|
||||
monsterType = player.race.getRaceType().getMonsterType();
|
||||
}
|
||||
|
||||
return monsterType != null && pb.monsterTypeRestrictions.contains(monsterType);
|
||||
}
|
||||
|
||||
public static void sendRecyclePower(int token, ClientConnection origin) {
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token);
|
||||
|
||||
@@ -1580,9 +1751,6 @@ public enum PowersManager {
|
||||
//Pet only
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), MBServerStatics.MASK_PET);
|
||||
else if (pb.targetNecroPet())
|
||||
allTargets = WorldGrid.getObjectsInRangePartialNecroPets(
|
||||
targetLoc, pb.getRadius());
|
||||
else
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), 0);
|
||||
@@ -1694,6 +1862,11 @@ public enum PowersManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isRestrictedMonsterType(awo, pb)) {
|
||||
awolist.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
|
||||
// Remove players who are in safe mode
|
||||
@@ -1779,9 +1952,6 @@ public enum PowersManager {
|
||||
//Pet only
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), MBServerStatics.MASK_PET);
|
||||
else if (pb.targetNecroPet())
|
||||
allTargets = WorldGrid.getObjectsInRangePartialNecroPets(
|
||||
targetLoc, pb.getRadius());
|
||||
else
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), 0);
|
||||
@@ -1846,6 +2016,11 @@ public enum PowersManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isRestrictedMonsterType(awo, pb)) {
|
||||
awolist.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
// Remove players who are in safe mode
|
||||
PlayerCharacter pcc = (PlayerCharacter) awo;
|
||||
@@ -2238,14 +2413,14 @@ public enum PowersManager {
|
||||
String outmsg = "Invalid Target";
|
||||
ChatManager.chatSystemInfo(pc, outmsg);
|
||||
return false; // can't target player, stop here
|
||||
} // target is mob
|
||||
} // target is pet; pets also carry MASK_MOB, so test them first. A pet is still a Mobile (client 0x49E440)
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0)
|
||||
return pb.targetPet() || pb.targetMob();
|
||||
|
||||
// target is mob
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0)
|
||||
return pb.targetMob();
|
||||
|
||||
// target is pet
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0)
|
||||
return pb.targetPet();
|
||||
|
||||
// target is Building
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_BUILDING) != 0)
|
||||
return pb.targetBuilding();
|
||||
@@ -2255,12 +2430,12 @@ public enum PowersManager {
|
||||
if (pb.targetItem())
|
||||
return true;
|
||||
// TODO add these checks later
|
||||
else if (pb.targetArmor() && item.template.item_type.equals(ItemType.ARMOR))
|
||||
else if (pb.targetArmor() && item.template.getItemType().equals(ItemType.ARMOR))
|
||||
return true;
|
||||
else if (pb.targetJewelry() && item.template.item_type.equals(ItemType.JEWELRY))
|
||||
else if (pb.targetJewelry() && item.template.getItemType().equals(ItemType.JEWELRY))
|
||||
return true;
|
||||
else
|
||||
return pb.targetWeapon() && item.template.item_type.equals(ItemType.WEAPON);
|
||||
return pb.targetWeapon() && item.template.getItemType().equals(ItemType.WEAPON);
|
||||
} // How did we get here? all valid targets have been covered
|
||||
else
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.gameManager;
|
||||
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.mbEnums.StaticBuildingMode;
|
||||
import engine.mbEnums.ZonePropType;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.Guild;
|
||||
import engine.objects.Zone;
|
||||
import engine.parsers.objects.CZonePlacement;
|
||||
import engine.parsers.objects.CZoneProp;
|
||||
import engine.parsers.objects.ZoneTreeEntry;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
// World Boot Plan 2.4: static buildings from the CZONE props of the static zones. IDs follow the zones, zone by
|
||||
// zone in tree order, top-level props in JSON order. Each prop's children take their IDs (JSON order) before
|
||||
// the prop itself, so the parent has the lowest ID of its family, as DB UIDs did. Never renumber.
|
||||
|
||||
public enum StaticBuildingLoader {
|
||||
|
||||
STATICBUILDINGLOADER;
|
||||
|
||||
private static final float TWIN_POSITION_TOLERANCE = 0.01f;
|
||||
private static final float TWIN_YAW_TOLERANCE = 0.0001f;
|
||||
|
||||
public static StaticBuildingMode getMode() {
|
||||
return StaticBuildingMode.fromConfig(ConfigManager.MB_STATIC_BUILDINGS.getValue());
|
||||
}
|
||||
|
||||
// addToWorld false (parity) builds every building with ID 0, outside the cache and the world grid; the
|
||||
// static IDs are still taken, so the manifest matches a JSON boot.
|
||||
|
||||
public static ArrayList<StaticBuildingEntry> buildStaticBuildings(boolean addToWorld) {
|
||||
|
||||
ArrayList<StaticBuildingEntry> topLevelEntries = new ArrayList<>();
|
||||
ArrayList<CZoneProp> keptZoneProps = new ArrayList<>();
|
||||
ArrayList<CZoneProp> keptChildProps = new ArrayList<>();
|
||||
ArrayList<Integer> keptChildIndexes = new ArrayList<>();
|
||||
ArrayList<Integer> childIDs = new ArrayList<>();
|
||||
HashMap<String, Integer> leadersByName;
|
||||
StaticBuildingEntry entry;
|
||||
StaticBuildingEntry childEntry;
|
||||
Zone zone;
|
||||
CZoneProp prop;
|
||||
CZoneProp childProp;
|
||||
String key;
|
||||
int buildingCount = 0;
|
||||
int twinCount;
|
||||
int totalTwins = 0;
|
||||
int ownerMissing = 0;
|
||||
int ownerUUID;
|
||||
|
||||
leadersByName = DbManager.StaticWorldQueries.GET_NPC_GUILD_LEADERS();
|
||||
|
||||
for (ZoneTreeEntry treeEntry : ZoneManager.zoneTree) {
|
||||
|
||||
zone = ZoneManager.staticZonesByTreeUID.get(treeEntry.uid);
|
||||
keptZoneProps.clear();
|
||||
twinCount = 0;
|
||||
|
||||
for (int propIndex = 0; propIndex < zone.template.zone_prop_info.size(); propIndex++) {
|
||||
|
||||
prop = zone.template.zone_prop_info.get(propIndex);
|
||||
|
||||
// A dropped twin takes its children with it
|
||||
if (isStackedTwin(prop, keptZoneProps)) {
|
||||
twinCount += 1 + prop.prop_content_props.size();
|
||||
continue;
|
||||
}
|
||||
|
||||
keptZoneProps.add(prop);
|
||||
key = "prop:" + treeEntry.uid + "/" + propIndex;
|
||||
keptChildProps.clear();
|
||||
keptChildIndexes.clear();
|
||||
childIDs.clear();
|
||||
|
||||
for (int childIndex = 0; childIndex < prop.prop_content_props.size(); childIndex++) {
|
||||
|
||||
childProp = prop.prop_content_props.get(childIndex);
|
||||
|
||||
if (isStackedTwin(childProp, keptChildProps)) {
|
||||
twinCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
keptChildProps.add(childProp);
|
||||
keptChildIndexes.add(childIndex);
|
||||
}
|
||||
|
||||
for (int childIndex : keptChildIndexes)
|
||||
childIDs.add(DbManager.nextStaticID(GameObjectType.Building, key + "/" + childIndex));
|
||||
|
||||
ownerUUID = getOwnerUUID(prop, leadersByName);
|
||||
|
||||
if (prop.prop_type == ZonePropType.CITY && ownerUUID == 0 && GuildManager._npcGuildsByKey.containsKey(prop.city_prop_gm_guild))
|
||||
ownerMissing++;
|
||||
|
||||
entry = buildEntry(treeEntry.uid, key, DbManager.nextStaticID(GameObjectType.Building, key), zone, prop, null, ownerUUID, addToWorld);
|
||||
topLevelEntries.add(entry);
|
||||
buildingCount++;
|
||||
|
||||
for (int i = 0; i < keptChildProps.size(); i++) {
|
||||
childEntry = buildEntry(treeEntry.uid, key + "/" + keptChildIndexes.get(i), childIDs.get(i), zone, keptChildProps.get(i), entry, 0, addToWorld);
|
||||
entry.children.add(childEntry);
|
||||
buildingCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (twinCount > 0)
|
||||
Logger.info("Static buildings: " + twinCount + " stacked twins dropped in zone " + treeEntry.uid + " (" + treeEntry.name + ")");
|
||||
|
||||
totalTwins += twinCount;
|
||||
}
|
||||
|
||||
if (ownerMissing > 0)
|
||||
Logger.warn("Static buildings: " + ownerMissing + " CITY props name a guild with no DB leader NPC; left unowned");
|
||||
|
||||
Logger.info("Static buildings: " + buildingCount + " built, " + totalTwins + " stacked twins dropped");
|
||||
|
||||
return topLevelEntries;
|
||||
}
|
||||
|
||||
private static StaticBuildingEntry buildEntry(int zoneTreeUID, String key, int staticID, Zone zone, CZoneProp prop, StaticBuildingEntry parentEntry,
|
||||
int ownerUUID, boolean addToWorld) {
|
||||
|
||||
StaticBuildingEntry entry = new StaticBuildingEntry();
|
||||
|
||||
entry.key = key;
|
||||
entry.zoneTreeUID = zoneTreeUID;
|
||||
entry.prop = prop;
|
||||
entry.parent = parentEntry;
|
||||
entry.staticID = staticID;
|
||||
entry.building = Building.createStaticBuilding(addToWorld ? entry.staticID : 0, zone, prop,
|
||||
parentEntry == null ? null : parentEntry.building, ownerUUID);
|
||||
|
||||
if (addToWorld) {
|
||||
DbManager.addToCache(entry.building);
|
||||
entry.building.runAfterLoad();
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
// Same mesh, name, local position and yaw as an earlier kept sibling (findings §6, stacked duplicates;
|
||||
// the name keeps Swampstone's stacked vendor halls).
|
||||
private static boolean isStackedTwin(CZoneProp prop, ArrayList<CZoneProp> keptSiblings) {
|
||||
|
||||
CZonePlacement placement = prop.prop_basic_zone;
|
||||
CZonePlacement keptPlacement;
|
||||
|
||||
for (CZoneProp kept : keptSiblings) {
|
||||
|
||||
keptPlacement = kept.prop_basic_zone;
|
||||
|
||||
if (keptPlacement.basic_zone_template_id != placement.basic_zone_template_id
|
||||
|| !keptPlacement.basic_zone_name_override.equals(placement.basic_zone_name_override))
|
||||
continue;
|
||||
|
||||
if (Math.abs(keptPlacement.basic_zone_spawn_location.x - placement.basic_zone_spawn_location.x) <= TWIN_POSITION_TOLERANCE
|
||||
&& Math.abs(keptPlacement.basic_zone_spawn_location.y - placement.basic_zone_spawn_location.y) <= TWIN_POSITION_TOLERANCE
|
||||
&& Math.abs(keptPlacement.basic_zone_spawn_location.z - placement.basic_zone_spawn_location.z) <= TWIN_POSITION_TOLERANCE
|
||||
&& Math.abs(keptPlacement.basic_zone_y_rot - placement.basic_zone_y_rot) <= TWIN_YAW_TOLERANCE)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The guild the CITY key names, owned through its DB leader NPC as before the switch.
|
||||
private static int getOwnerUUID(CZoneProp prop, HashMap<String, Integer> leadersByName) {
|
||||
|
||||
Guild guild;
|
||||
Integer leaderUUID;
|
||||
|
||||
if (prop.prop_type != ZonePropType.CITY)
|
||||
return 0;
|
||||
|
||||
guild = GuildManager._npcGuildsByKey.get(prop.city_prop_gm_guild);
|
||||
|
||||
if (guild == null)
|
||||
return 0;
|
||||
|
||||
leaderUUID = leadersByName.get(guild.getName());
|
||||
|
||||
return leaderUUID == null ? 0 : leaderUUID;
|
||||
}
|
||||
|
||||
public static class StaticBuildingEntry {
|
||||
|
||||
public String key;
|
||||
public int zoneTreeUID;
|
||||
public int staticID;
|
||||
public CZoneProp prop;
|
||||
public Building building;
|
||||
public StaticBuildingEntry parent;
|
||||
public final ArrayList<StaticBuildingEntry> children = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.gameManager;
|
||||
|
||||
import engine.gameManager.StaticBuildingLoader.StaticBuildingEntry;
|
||||
import engine.math.Quaternion;
|
||||
import engine.mbEnums.ZonePropType;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.Guild;
|
||||
import engine.objects.Zone;
|
||||
import engine.parsers.objects.CZoneProp;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
// World Boot Plan 2.3/2.4: builds the static buildings from the CZONE props with the IDs a JSON boot gives them,
|
||||
// compares them with the DB buildings they replace, and writes maps/<map>.migration.sql, the old UID -> static ID
|
||||
// mapping the 2.4 migration script re-points references with. The JSON buildings are discarded.
|
||||
|
||||
public enum StaticBuildingParity {
|
||||
|
||||
STATICBUILDINGPARITY;
|
||||
|
||||
private static final String mapPath = ConfigManager.DEFAULT_DATA_DIR + "maps/";
|
||||
private static final float POSITION_TOLERANCE = 0.01f;
|
||||
private static final float ROTATION_TOLERANCE = 0.0001f;
|
||||
private static final int EXAMPLES = 5;
|
||||
private static final int INSERT_BATCH = 500;
|
||||
private static final String DB_ONLY = "DB only (unmapped, deleted by the migration)";
|
||||
|
||||
private static final TreeMap<String, ArrayList<String>> differences = new TreeMap<>();
|
||||
private static final HashMap<Integer, StaticBuildingEntry> entriesByDbUID = new HashMap<>();
|
||||
private static final HashSet<StaticBuildingEntry> matchedEntries = new HashSet<>();
|
||||
private static final HashMap<Integer, ArrayList<Building>> dbChildrenByParent = new HashMap<>();
|
||||
private static int propCount;
|
||||
private static int exactCount;
|
||||
private static int movedCount;
|
||||
private static int twinCount;
|
||||
private static float maxChildMove;
|
||||
|
||||
// Run after NPCs load, so a DB building's owner resolves to its guild.
|
||||
public static void run(int mapID) {
|
||||
|
||||
ArrayList<StaticBuildingEntry> topLevelEntries;
|
||||
HashMap<Integer, ArrayList<StaticBuildingEntry>> entriesByZone = new HashMap<>();
|
||||
HashMap<Integer, ArrayList<Building>> dbTopLevelByZone = new HashMap<>();
|
||||
ArrayList<Building> dbStatic = new ArrayList<>();
|
||||
ArrayList<Building> dbUnmatchedTop = new ArrayList<>();
|
||||
Building dbBuilding;
|
||||
|
||||
topLevelEntries = StaticBuildingLoader.buildStaticBuildings(false);
|
||||
|
||||
for (StaticBuildingEntry entry : topLevelEntries) {
|
||||
entriesByZone.computeIfAbsent(entry.zoneTreeUID, k -> new ArrayList<>()).add(entry);
|
||||
propCount += 1 + entry.children.size();
|
||||
}
|
||||
|
||||
// Mine towers (blueprint 1500100) stay DB objects (Task 2.1, D1); every CZONE prop has blueprint 0.
|
||||
for (Zone zone : ZoneManager.staticZonesByTreeUID.values())
|
||||
for (Building building : zone.zoneBuildingSet) {
|
||||
|
||||
if (building.blueprintUUID != 0)
|
||||
continue;
|
||||
|
||||
dbStatic.add(building);
|
||||
|
||||
if (building.parentBuildingID == 0)
|
||||
dbTopLevelByZone.computeIfAbsent(zone.getObjectUUID(), k -> new ArrayList<>()).add(building);
|
||||
else
|
||||
dbChildrenByParent.computeIfAbsent(building.parentBuildingID, k -> new ArrayList<>()).add(building);
|
||||
}
|
||||
|
||||
// Pass 1: zone, mesh and local x/z.
|
||||
for (Map.Entry<Integer, ArrayList<StaticBuildingEntry>> zoneEntries : entriesByZone.entrySet())
|
||||
for (StaticBuildingEntry entry : zoneEntries.getValue()) {
|
||||
|
||||
dbBuilding = takeMatch(entry, dbTopLevelByZone.getOrDefault(zoneEntries.getKey(), new ArrayList<>()));
|
||||
|
||||
if (dbBuilding == null)
|
||||
continue;
|
||||
|
||||
exactCount++;
|
||||
mapPair(dbBuilding, entry, true);
|
||||
}
|
||||
|
||||
for (ArrayList<Building> leftovers : dbTopLevelByZone.values())
|
||||
dbUnmatchedTop.addAll(leftovers);
|
||||
|
||||
// Pass 2: hand-moved DB rows (Swampstone halls, Silverlance shop).
|
||||
for (Building building : new ArrayList<>(dbUnmatchedTop)) {
|
||||
|
||||
StaticBuildingEntry entry = findMovedMatch(building, entriesByZone);
|
||||
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
dbUnmatchedTop.remove(building);
|
||||
movedCount++;
|
||||
mapPair(building, entry, true);
|
||||
}
|
||||
|
||||
// Pass 3: a DB row of a dropped stacked twin maps to the kept twin.
|
||||
for (Building building : new ArrayList<>(dbUnmatchedTop)) {
|
||||
|
||||
StaticBuildingEntry entry = findTwin(building, entriesByZone.getOrDefault(building.parentZoneUUID, new ArrayList<>()));
|
||||
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
dbUnmatchedTop.remove(building);
|
||||
twinCount++;
|
||||
mapPair(building, entry, false);
|
||||
}
|
||||
|
||||
logResults(dbStatic, topLevelEntries);
|
||||
writeMigration(mapID, dbStatic);
|
||||
|
||||
differences.clear();
|
||||
entriesByDbUID.clear();
|
||||
matchedEntries.clear();
|
||||
dbChildrenByParent.clear();
|
||||
}
|
||||
|
||||
// Maps a DB top-level row and its children. compare is false for twins: their differences are the kept twin's.
|
||||
private static void mapPair(Building dbBuilding, StaticBuildingEntry entry, boolean compare) {
|
||||
|
||||
ArrayList<Building> dbChildren = dbChildrenByParent.getOrDefault(dbBuilding.getObjectUUID(), new ArrayList<>());
|
||||
ArrayList<Building> dbChildCandidates = new ArrayList<>(dbChildren);
|
||||
Building dbChild;
|
||||
StaticBuildingEntry twin;
|
||||
float childMove;
|
||||
|
||||
entriesByDbUID.put(dbBuilding.getObjectUUID(), entry);
|
||||
|
||||
if (compare) {
|
||||
matchedEntries.add(entry);
|
||||
compareBuilding(entry, dbBuilding);
|
||||
}
|
||||
|
||||
for (StaticBuildingEntry childEntry : entry.children) {
|
||||
|
||||
dbChild = takeMatch(childEntry, dbChildCandidates);
|
||||
|
||||
if (dbChild == null)
|
||||
continue;
|
||||
|
||||
entriesByDbUID.put(dbChild.getObjectUUID(), childEntry);
|
||||
|
||||
if (!compare)
|
||||
continue;
|
||||
|
||||
matchedEntries.add(childEntry);
|
||||
compareBuilding(childEntry, dbChild);
|
||||
|
||||
if (Math.abs(dbChild.getStatAlt() - childEntry.building.getStatAlt()) > POSITION_TOLERANCE)
|
||||
addDifference("child local Y", childEntry.key + " DB " + dbChild.getStatAlt() + " JSON " + childEntry.building.getStatAlt());
|
||||
|
||||
// Today's runAfterLoad adds the child offset without the parent's yaw.
|
||||
childMove = dbChild.getLoc().distance2D(childEntry.building.getLoc());
|
||||
|
||||
if (childMove > POSITION_TOLERANCE) {
|
||||
addDifference("child world x/z (parent yaw)", childEntry.key + " moved " + childMove);
|
||||
maxChildMove = Math.max(maxChildMove, childMove);
|
||||
}
|
||||
}
|
||||
|
||||
// DB children of dropped twin children map to the kept child.
|
||||
for (Building leftover : dbChildCandidates) {
|
||||
|
||||
twin = findTwin(leftover, entry.children);
|
||||
|
||||
if (twin != null)
|
||||
entriesByDbUID.put(leftover.getObjectUUID(), twin);
|
||||
}
|
||||
}
|
||||
|
||||
// Same mesh and local x/z; removes and returns the closest DB building, or null.
|
||||
private static Building takeMatch(StaticBuildingEntry entry, ArrayList<Building> candidates) {
|
||||
|
||||
Building found = null;
|
||||
float foundDistance = Float.MAX_VALUE;
|
||||
float distance;
|
||||
|
||||
for (Building candidate : candidates) {
|
||||
|
||||
distance = localDistance(candidate, entry);
|
||||
|
||||
if (distance <= POSITION_TOLERANCE && distance < foundDistance) {
|
||||
found = candidate;
|
||||
foundDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (found != null)
|
||||
candidates.remove(found);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// An unmatched JSON prop with the same mesh in the DB row's zone or its parent zone: same name first,
|
||||
// otherwise the only candidate.
|
||||
private static StaticBuildingEntry findMovedMatch(Building dbBuilding, HashMap<Integer, ArrayList<StaticBuildingEntry>> entriesByZone) {
|
||||
|
||||
ArrayList<StaticBuildingEntry> candidates = new ArrayList<>();
|
||||
Zone zone = ZoneManager.getZoneByUUID(dbBuilding.parentZoneUUID);
|
||||
|
||||
addMovedCandidates(dbBuilding, entriesByZone.get(zone.getObjectUUID()), candidates);
|
||||
|
||||
if (zone.parent != null && zone.parent.isStaticWorldObject())
|
||||
addMovedCandidates(dbBuilding, entriesByZone.get(zone.parent.getObjectUUID()), candidates);
|
||||
|
||||
for (StaticBuildingEntry candidate : candidates)
|
||||
if (candidate.building.getName().equals(dbBuilding.getName()))
|
||||
return candidate;
|
||||
|
||||
return candidates.size() == 1 ? candidates.get(0) : null;
|
||||
}
|
||||
|
||||
private static void addMovedCandidates(Building dbBuilding, ArrayList<StaticBuildingEntry> zoneEntries, ArrayList<StaticBuildingEntry> candidates) {
|
||||
|
||||
if (zoneEntries == null)
|
||||
return;
|
||||
|
||||
for (StaticBuildingEntry entry : zoneEntries)
|
||||
if (!matchedEntries.contains(entry) && entry.building.meshUUID == dbBuilding.meshUUID)
|
||||
candidates.add(entry);
|
||||
}
|
||||
|
||||
// Any kept entry, matched or not, with the same mesh and local x/z.
|
||||
private static StaticBuildingEntry findTwin(Building dbBuilding, ArrayList<StaticBuildingEntry> siblings) {
|
||||
|
||||
for (StaticBuildingEntry entry : siblings)
|
||||
if (localDistance(dbBuilding, entry) <= POSITION_TOLERANCE)
|
||||
return entry;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Chebyshev distance on local x/z for the same mesh; MAX_VALUE for a different mesh.
|
||||
private static float localDistance(Building dbBuilding, StaticBuildingEntry entry) {
|
||||
|
||||
if (dbBuilding.meshUUID != entry.building.meshUUID)
|
||||
return Float.MAX_VALUE;
|
||||
|
||||
return Math.max(Math.abs(dbBuilding.statLat - entry.building.statLat), Math.abs(dbBuilding.statLon - entry.building.statLon));
|
||||
}
|
||||
|
||||
private static void logResults(ArrayList<Building> dbStatic, ArrayList<StaticBuildingEntry> topLevelEntries) {
|
||||
|
||||
for (Building building : dbStatic)
|
||||
if (!entriesByDbUID.containsKey(building.getObjectUUID()))
|
||||
addDifference(DB_ONLY, building.getObjectUUID() + " zone " + building.parentZoneUUID + " mesh " + building.meshUUID
|
||||
+ " '" + building.getName() + "' at " + building.statLat + ", " + building.statLon + " parent " + building.parentBuildingID);
|
||||
|
||||
for (StaticBuildingEntry entry : topLevelEntries) {
|
||||
|
||||
if (!matchedEntries.contains(entry))
|
||||
addDifference("JSON only", entry.key + " mesh " + entry.building.meshUUID + " '" + entry.building.getName() + "'");
|
||||
|
||||
for (StaticBuildingEntry childEntry : entry.children)
|
||||
if (!matchedEntries.contains(childEntry))
|
||||
addDifference("JSON only", childEntry.key + " mesh " + childEntry.building.meshUUID + " '" + childEntry.building.getName() + "'");
|
||||
}
|
||||
|
||||
Logger.info("Static building parity: " + propCount + " props, " + dbStatic.size() + " DB rows, " + entriesByDbUID.size()
|
||||
+ " mapped (" + exactCount + " top-level exact, " + movedCount + " moved, " + twinCount + " twins, rest children)"
|
||||
+ ", max child x/z move from the parent yaw " + maxChildMove);
|
||||
|
||||
// Every unmapped DB row is listed in full: the migration deletes it, so its references must be checked.
|
||||
for (Map.Entry<String, ArrayList<String>> entry : differences.entrySet()) {
|
||||
|
||||
Logger.info(" " + entry.getKey() + ": " + entry.getValue().size());
|
||||
|
||||
for (int i = 0; i < entry.getValue().size(); i++)
|
||||
if (i < EXAMPLES || entry.getKey().equals(DB_ONLY))
|
||||
Logger.info(" " + entry.getValue().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
// task24_static_map: every static zone (tree UID -> static ID) and every DB static building (UID -> static ID,
|
||||
// or NULL when unmapped). sql/task24_static_switch.sql reads it.
|
||||
private static void writeMigration(int mapID, ArrayList<Building> dbStatic) {
|
||||
|
||||
File migrationFile = new File(mapPath + mapID + ".migration.sql");
|
||||
ArrayList<String> rows = new ArrayList<>();
|
||||
StringBuilder sql = new StringBuilder();
|
||||
StaticBuildingEntry entry;
|
||||
|
||||
for (Map.Entry<Integer, Integer> zoneID : new TreeMap<>(ZoneManager.staticIDsByTreeUID).entrySet())
|
||||
rows.add("(" + zoneID.getKey() + ", " + zoneID.getValue() + ", 'zone', 'zone:" + zoneID.getKey() + "')");
|
||||
|
||||
for (Building building : dbStatic) {
|
||||
|
||||
entry = entriesByDbUID.get(building.getObjectUUID());
|
||||
|
||||
if (entry == null)
|
||||
rows.add("(" + building.getObjectUUID() + ", NULL, 'building', NULL)");
|
||||
else
|
||||
rows.add("(" + building.getObjectUUID() + ", " + entry.staticID + ", 'building', '" + entry.key + "')");
|
||||
}
|
||||
|
||||
sql.append("-- World Boot Plan 2.4: old UID -> static ID for map ").append(mapID).append(", written by MB_STATIC_BUILDINGS=parity.\n");
|
||||
sql.append("DROP TABLE IF EXISTS `task24_static_map`;\n");
|
||||
sql.append("CREATE TABLE `task24_static_map` (`oldUID` BIGINT UNSIGNED NOT NULL, `newID` INT NULL, ")
|
||||
.append("`kind` ENUM('zone','building') NOT NULL, `staticKey` VARCHAR(64) NULL, PRIMARY KEY (`oldUID`));\n");
|
||||
|
||||
for (int i = 0; i < rows.size(); i++) {
|
||||
|
||||
if (i % INSERT_BATCH == 0)
|
||||
sql.append("INSERT INTO `task24_static_map` VALUES\n");
|
||||
|
||||
sql.append(rows.get(i));
|
||||
sql.append(i % INSERT_BATCH == INSERT_BATCH - 1 || i == rows.size() - 1 ? ";\n" : ",\n");
|
||||
}
|
||||
|
||||
try {
|
||||
Files.write(migrationFile.toPath(), sql.toString().getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
Logger.error("Static migration mapping not written: " + migrationFile.getAbsolutePath() + ": " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.info("Static migration mapping: " + rows.size() + " rows written to " + migrationFile.getName());
|
||||
}
|
||||
|
||||
private static void compareBuilding(StaticBuildingEntry entry, Building dbBuilding) {
|
||||
|
||||
Building jsonBuilding = entry.building;
|
||||
CZoneProp prop = entry.prop;
|
||||
String prefix = entry.key + " (DB " + dbBuilding.getObjectUUID() + ")";
|
||||
String dbGuild = guildName(dbBuilding);
|
||||
String jsonGuild = "";
|
||||
|
||||
if (!sameRotation(dbBuilding.getRotation(), jsonBuilding.getRotation()))
|
||||
addDifference("rotation", prefix + " DB " + rotationText(dbBuilding.getRotation()) + " JSON " + rotationText(jsonBuilding.getRotation()));
|
||||
|
||||
if (!dbBuilding.getMeshScale().equals(jsonBuilding.getMeshScale()))
|
||||
addDifference("scale", prefix + " DB " + dbBuilding.getMeshScale() + " JSON " + jsonBuilding.getMeshScale());
|
||||
|
||||
if (dbBuilding.rank != jsonBuilding.rank)
|
||||
addDifference("rank", prefix + " DB " + dbBuilding.rank + " JSON " + jsonBuilding.rank);
|
||||
|
||||
if (dbBuilding.getStrongboxValue() != jsonBuilding.getStrongboxValue())
|
||||
addDifference("strongbox", prefix + " DB " + dbBuilding.getStrongboxValue() + " JSON " + jsonBuilding.getStrongboxValue());
|
||||
|
||||
if (!dbBuilding.getName().equals(jsonBuilding.getName()))
|
||||
addDifference("name", prefix + " DB '" + dbBuilding.getName() + "' JSON '" + jsonBuilding.getName() + "'");
|
||||
|
||||
if (dbBuilding.floor != jsonBuilding.floor || dbBuilding.level != jsonBuilding.level)
|
||||
addDifference("floor/level", prefix + " DB " + dbBuilding.floor + "/" + dbBuilding.level + " JSON " + jsonBuilding.floor + "/" + jsonBuilding.level);
|
||||
|
||||
if (dbBuilding.protectionState != jsonBuilding.protectionState)
|
||||
addDifference("protection", prefix + " DB " + dbBuilding.protectionState + " JSON " + jsonBuilding.protectionState);
|
||||
|
||||
if (dbBuilding.isFurniture != jsonBuilding.isFurniture)
|
||||
addDifference("furniture flag", prefix + " DB " + dbBuilding.isFurniture + " JSON " + jsonBuilding.isFurniture);
|
||||
|
||||
if (dbBuilding.getOwnerUUID() != jsonBuilding.getOwnerUUID())
|
||||
addDifference("owner NPC", prefix + " DB " + dbBuilding.getOwnerUUID() + " JSON " + jsonBuilding.getOwnerUUID());
|
||||
|
||||
if (prop.prop_type == ZonePropType.CITY && GuildManager._npcGuildsByKey.containsKey(prop.city_prop_gm_guild))
|
||||
jsonGuild = GuildManager._npcGuildsByKey.get(prop.city_prop_gm_guild).getName();
|
||||
|
||||
if (!dbGuild.equals(jsonGuild))
|
||||
addDifference("owner guild", prefix + " DB '" + dbGuild + "' JSON '" + jsonGuild + "'");
|
||||
}
|
||||
|
||||
// q and -q are the same rotation.
|
||||
private static boolean sameRotation(Quaternion a, Quaternion b) {
|
||||
|
||||
boolean same = Math.abs(a.w - b.w) < ROTATION_TOLERANCE && Math.abs(a.x - b.x) < ROTATION_TOLERANCE
|
||||
&& Math.abs(a.y - b.y) < ROTATION_TOLERANCE && Math.abs(a.z - b.z) < ROTATION_TOLERANCE;
|
||||
boolean negated = Math.abs(a.w + b.w) < ROTATION_TOLERANCE && Math.abs(a.x + b.x) < ROTATION_TOLERANCE
|
||||
&& Math.abs(a.y + b.y) < ROTATION_TOLERANCE && Math.abs(a.z + b.z) < ROTATION_TOLERANCE;
|
||||
|
||||
return same || negated;
|
||||
}
|
||||
|
||||
private static String rotationText(Quaternion rotation) {
|
||||
return "(w " + rotation.w + ", x " + rotation.x + ", y " + rotation.y + ", z " + rotation.z + ")";
|
||||
}
|
||||
|
||||
private static String guildName(Building building) {
|
||||
|
||||
Guild guild;
|
||||
|
||||
if (building.getOwnerUUID() == 0)
|
||||
return "";
|
||||
|
||||
guild = building.getGuild();
|
||||
|
||||
return guild == null || guild.isEmptyGuild() ? "" : guild.getName();
|
||||
}
|
||||
|
||||
private static void addDifference(String differenceClass, String line) {
|
||||
differences.computeIfAbsent(differenceClass, k -> new ArrayList<>()).add(line);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.gameManager;
|
||||
|
||||
import engine.gameManager.StaticBuildingLoader.StaticBuildingEntry;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.mbEnums.ZonePropType;
|
||||
import engine.objects.City;
|
||||
import engine.objects.Guild;
|
||||
import engine.objects.Zone;
|
||||
import engine.parsers.objects.GuildSeedEntry;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
// World Boot Plan 2.5: one NPC city per seed guild, in the zone of the guild's first CITY prop (tree order, then JSON
|
||||
// order); that prop is the tree of life. Later zones with the same guild (Junktown under Swampstone) are not cities.
|
||||
// City IDs follow all static buildings. Never renumber.
|
||||
|
||||
public enum StaticCityLoader {
|
||||
|
||||
STATICCITYLOADER;
|
||||
|
||||
// addToWorld false (parity) keeps the cities out of the cache and the guilds; the static IDs are still taken.
|
||||
public static ArrayList<StaticCityEntry> buildStaticCities(ArrayList<StaticBuildingEntry> topLevelEntries, boolean addToWorld) {
|
||||
|
||||
ArrayList<StaticCityEntry> cityEntries = new ArrayList<>();
|
||||
HashSet<Guild> guildsWithCity = new HashSet<>();
|
||||
StaticCityEntry cityEntry;
|
||||
GuildSeedEntry seedEntry;
|
||||
Guild guild;
|
||||
Zone zone;
|
||||
|
||||
for (StaticBuildingEntry buildingEntry : topLevelEntries) {
|
||||
|
||||
if (buildingEntry.prop.prop_type != ZonePropType.CITY)
|
||||
continue;
|
||||
|
||||
guild = GuildManager._npcGuildsByKey.get(buildingEntry.prop.city_prop_gm_guild);
|
||||
|
||||
if (guild == null || !guildsWithCity.add(guild))
|
||||
continue;
|
||||
|
||||
zone = ZoneManager.staticZonesByTreeUID.get(buildingEntry.zoneTreeUID);
|
||||
seedEntry = GuildManager._npcSeedEntriesByGuildID.get(guild.getObjectUUID());
|
||||
|
||||
cityEntry = new StaticCityEntry();
|
||||
cityEntry.key = "city:" + buildingEntry.key.substring("prop:".length());
|
||||
cityEntry.staticID = DbManager.nextStaticID(GameObjectType.City, cityEntry.key);
|
||||
cityEntry.guild = guild;
|
||||
cityEntry.treeEntry = buildingEntry;
|
||||
cityEntry.city = City.createStaticCity(addToWorld ? cityEntry.staticID : 0, zone, buildingEntry.building, seedEntry.noobIsle);
|
||||
cityEntries.add(cityEntry);
|
||||
|
||||
if (addToWorld) {
|
||||
DbManager.addToCache(cityEntry.city);
|
||||
guild.setCityUUID(cityEntry.staticID);
|
||||
cityEntry.city.runAfterLoad();
|
||||
}
|
||||
}
|
||||
|
||||
if (guildsWithCity.size() < GuildManager._npcSeedEntriesByGuildID.size())
|
||||
Logger.warn("Static cities: " + (GuildManager._npcSeedEntriesByGuildID.size() - guildsWithCity.size())
|
||||
+ " seed guilds have no CITY prop on this map");
|
||||
|
||||
Logger.info("Static cities: " + cityEntries.size() + " built");
|
||||
|
||||
return cityEntries;
|
||||
}
|
||||
|
||||
public static class StaticCityEntry {
|
||||
|
||||
public String key;
|
||||
public int staticID;
|
||||
public Guild guild;
|
||||
public StaticBuildingEntry treeEntry;
|
||||
public City city;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.gameManager;
|
||||
|
||||
import engine.gameManager.StaticCityLoader.StaticCityEntry;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.City;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
// World Boot Plan 2.5: while obj_city still holds the NPC cities, compares them with the JSON cities (matched by
|
||||
// parent zone) and writes maps/<map>.city_migration.sql, the old UID -> static ID mapping that
|
||||
// sql/task25_static_cities.sql re-points obj_guild.ownedCity with. The JSON cities are discarded.
|
||||
|
||||
public enum StaticCityParity {
|
||||
|
||||
STATICCITYPARITY;
|
||||
|
||||
private static final String mapPath = ConfigManager.DEFAULT_DATA_DIR + "maps/";
|
||||
|
||||
// Run after NPCs load, so a tree's owner resolves to its guild.
|
||||
public static void run(int mapID, ArrayList<StaticCityEntry> cityEntries) {
|
||||
|
||||
HashMap<Integer, StaticCityEntry> entriesByZone = new HashMap<>();
|
||||
HashMap<Integer, StaticCityEntry> entriesByDbUID = new HashMap<>();
|
||||
ArrayList<City> dbCities = new ArrayList<>();
|
||||
ArrayList<String> differences = new ArrayList<>();
|
||||
StaticCityEntry entry;
|
||||
City dbCity;
|
||||
int jsonOnly = 0;
|
||||
|
||||
for (StaticCityEntry cityEntry : cityEntries)
|
||||
entriesByZone.put(cityEntry.city.parentZoneUUID, cityEntry);
|
||||
|
||||
for (AbstractGameObject gameObject : DbManager.getMap(GameObjectType.City).values()) {
|
||||
|
||||
dbCity = (City) gameObject;
|
||||
|
||||
if (dbCity.isNpc())
|
||||
dbCities.add(dbCity);
|
||||
}
|
||||
|
||||
for (City city : dbCities) {
|
||||
|
||||
entry = entriesByZone.get(city.parentZoneUUID);
|
||||
|
||||
if (entry == null) {
|
||||
differences.add("DB only: " + city.getObjectUUID() + " " + city.getCityName() + " zone " + city.parentZoneUUID);
|
||||
continue;
|
||||
}
|
||||
|
||||
entriesByDbUID.put(city.getObjectUUID(), entry);
|
||||
compareCity(city, entry, differences);
|
||||
}
|
||||
|
||||
for (StaticCityEntry cityEntry : cityEntries)
|
||||
if (!entriesByDbUID.containsValue(cityEntry)) {
|
||||
differences.add("JSON only: " + cityEntry.key + " " + cityEntry.city.getCityName());
|
||||
jsonOnly++;
|
||||
}
|
||||
|
||||
Logger.info("Static city parity: " + dbCities.size() + " DB NPC cities, " + cityEntries.size() + " JSON cities, "
|
||||
+ entriesByDbUID.size() + " matched, " + jsonOnly + " JSON only, " + differences.size() + " differences");
|
||||
|
||||
for (String difference : differences)
|
||||
Logger.info(" " + difference);
|
||||
|
||||
writeMigration(mapID, dbCities, entriesByDbUID);
|
||||
}
|
||||
|
||||
private static void compareCity(City dbCity, StaticCityEntry entry, ArrayList<String> differences) {
|
||||
|
||||
City jsonCity = entry.city;
|
||||
Building dbTree = dbCity.getTOL();
|
||||
String label = dbCity.getObjectUUID() + " " + dbCity.getCityName() + " (" + entry.key + ")";
|
||||
|
||||
compare(differences, label, "name", dbCity.getCityName(), jsonCity.getCityName());
|
||||
compare(differences, label, "tree", describeTree(dbTree), describeTree(jsonCity.getTOL()));
|
||||
compare(differences, label, "rank", dbCity.getRank(), jsonCity.getRank());
|
||||
compare(differences, label, "guild", dbCity.getGuild().getName(), entry.guild.getName());
|
||||
compare(differences, label, "noob isle", dbCity.isNoobIsle, jsonCity.isNoobIsle);
|
||||
compare(differences, label, "safehold", dbCity.isSafeHold(), jsonCity.isSafeHold());
|
||||
compare(differences, label, "established", dbCity.established, jsonCity.established);
|
||||
compare(differences, label, "sieges withstood", dbCity.getSiegesWithstood(), jsonCity.getSiegesWithstood());
|
||||
compare(differences, label, "open", dbCity.isOpen(), jsonCity.isOpen());
|
||||
compare(differences, label, "force rename", dbCity.isForceRename(), jsonCity.isForceRename());
|
||||
compare(differences, label, "bind x/z", dbCity.getBindX() + "/" + dbCity.getBindZ(), jsonCity.getBindX() + "/" + jsonCity.getBindZ());
|
||||
compare(differences, label, "bind radius", dbCity.getBindRadius() + " type " + dbCity.getRadiusType(),
|
||||
jsonCity.getBindRadius() + " type " + jsonCity.getRadiusType());
|
||||
}
|
||||
|
||||
private static String describeTree(Building tree) {
|
||||
|
||||
if (tree == null)
|
||||
return "none";
|
||||
|
||||
return tree.getObjectUUID() + " mesh " + tree.meshUUID;
|
||||
}
|
||||
|
||||
private static void compare(ArrayList<String> differences, String label, String field, Object dbValue, Object jsonValue) {
|
||||
|
||||
if (!Objects.equals(dbValue, jsonValue))
|
||||
differences.add(label + " " + field + ": DB " + dbValue + ", JSON " + jsonValue);
|
||||
}
|
||||
|
||||
// task25_city_map: every DB NPC city (UID -> static ID, or NULL when unmatched).
|
||||
private static void writeMigration(int mapID, ArrayList<City> dbCities, HashMap<Integer, StaticCityEntry> entriesByDbUID) {
|
||||
|
||||
File migrationFile = new File(mapPath + mapID + ".city_migration.sql");
|
||||
StringBuilder sql = new StringBuilder();
|
||||
StaticCityEntry entry;
|
||||
|
||||
sql.append("-- World Boot Plan 2.5: old NPC city UID -> static ID for map ").append(mapID)
|
||||
.append(", written by a JSON boot while obj_city still holds the NPC cities.\n");
|
||||
sql.append("DROP TABLE IF EXISTS `task25_city_map`;\n");
|
||||
sql.append("CREATE TABLE `task25_city_map` (`oldUID` BIGINT UNSIGNED NOT NULL, `newID` INT NULL, ")
|
||||
.append("`staticKey` VARCHAR(64) NULL, PRIMARY KEY (`oldUID`));\n");
|
||||
sql.append("INSERT INTO `task25_city_map` VALUES\n");
|
||||
|
||||
for (int i = 0; i < dbCities.size(); i++) {
|
||||
|
||||
entry = entriesByDbUID.get(dbCities.get(i).getObjectUUID());
|
||||
|
||||
if (entry == null)
|
||||
sql.append("(").append(dbCities.get(i).getObjectUUID()).append(", NULL, NULL)");
|
||||
else
|
||||
sql.append("(").append(dbCities.get(i).getObjectUUID()).append(", ").append(entry.staticID)
|
||||
.append(", '").append(entry.key).append("')");
|
||||
|
||||
sql.append(i == dbCities.size() - 1 ? ";\n" : ",\n");
|
||||
}
|
||||
|
||||
try {
|
||||
Files.write(migrationFile.toPath(), sql.toString().getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
Logger.error("Static city migration mapping not written: " + migrationFile.getAbsolutePath() + ": " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.info("Static city migration mapping: " + dbCities.size() + " rows written to " + migrationFile.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.gameManager;
|
||||
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.parsers.cache.CacheParserUtil;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// W2 safety net: every static ID with its natural key, in load order, written to maps/<map>.manifest at boot.
|
||||
// Diffing against the previous boot's file shows IDs that moved; the orphan check shows DB references they broke.
|
||||
|
||||
public enum StaticManifest {
|
||||
|
||||
STATICMANIFEST;
|
||||
|
||||
private static final String mapPath = ConfigManager.DEFAULT_DATA_DIR + "maps/";
|
||||
|
||||
// Player data columns that can hold a static ID (findings §5, Task 2.1). A null type accepts any static object.
|
||||
private static final String[][] referenceColumns = {
|
||||
{"object", "parent", null},
|
||||
{"obj_character", "char_bindBuilding", "Building"},
|
||||
{"obj_character", "guildUID", "Guild"},
|
||||
{"dyn_character_guildhistory", "GuildID", "Guild"},
|
||||
{"dyn_guild_allianceenemylist", "OtherGuildID", "Guild"},
|
||||
{"dyn_guild_guildkoslist", "KOSGuildID", "Guild"},
|
||||
{"obj_mob", "mob_buildingID", "Building"},
|
||||
{"obj_mob", "mob_guildUID", "Guild"},
|
||||
{"obj_npc", "npc_buildingID", "Building"},
|
||||
{"obj_npc", "npc_guildID", "Guild"},
|
||||
{"obj_city", "treeOfLifeUUID", "Building"},
|
||||
{"obj_guild", "ownedCity", "City"},
|
||||
{"static_runegate_portals", "sourceBuilding", "Building"},
|
||||
{"static_runegate_portals", "targetBuilding", "Building"},
|
||||
{"obj_mine", "mine_buildingUID", "Building"}
|
||||
};
|
||||
|
||||
private static final int LOGGED_MOVES = 20;
|
||||
|
||||
private static final ArrayList<ManifestEntry> entries = new ArrayList<>();
|
||||
private static final HashMap<Integer, ManifestEntry> entriesByID = new HashMap<>();
|
||||
private static final HashMap<String, ManifestEntry> entriesByKey = new HashMap<>();
|
||||
|
||||
public static void addEntry(int staticID, GameObjectType objectType, String key) {
|
||||
|
||||
ManifestEntry entry = new ManifestEntry(staticID, objectType.name(), key);
|
||||
|
||||
if (entriesByKey.containsKey(key))
|
||||
throw new IllegalStateException("Static manifest key " + key + " is used twice");
|
||||
|
||||
entries.add(entry);
|
||||
entriesByID.put(staticID, entry);
|
||||
entriesByKey.put(key, entry);
|
||||
}
|
||||
|
||||
// Logs moved, vanished and re-targeted IDs against the previous manifest, then replaces it (old copy kept as .prev).
|
||||
// Moved IDs leave DB references on the wrong objects: they are written to <map>.renumber.sql and the count is
|
||||
// returned so boot can stop before play.
|
||||
|
||||
public static int writeManifest(int mapID) {
|
||||
|
||||
File manifestFile = new File(mapPath + mapID + ".manifest");
|
||||
File previousFile = new File(mapPath + mapID + ".manifest.prev");
|
||||
HashMap<String, ManifestEntry> previousByKey;
|
||||
StringBuilder manifestText = new StringBuilder();
|
||||
ArrayList<ManifestEntry[]> movedEntries = new ArrayList<>();
|
||||
|
||||
previousByKey = readManifest(manifestFile, mapID);
|
||||
|
||||
if (previousByKey != null) {
|
||||
diffManifest(previousByKey, movedEntries);
|
||||
|
||||
if (!movedEntries.isEmpty())
|
||||
writeRenumber(mapID, movedEntries);
|
||||
}
|
||||
|
||||
manifestText.append("{\n \"map\": ").append(mapID).append(",\n \"count\": ").append(entries.size())
|
||||
.append(",\n \"statics\": [\n");
|
||||
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
manifestText.append(" ").append(entries.get(i).toJson());
|
||||
manifestText.append(i < entries.size() - 1 ? ",\n" : "\n");
|
||||
}
|
||||
|
||||
manifestText.append(" ]\n}\n");
|
||||
|
||||
try {
|
||||
if (manifestFile.exists())
|
||||
Files.copy(manifestFile.toPath(), previousFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
Files.write(manifestFile.toPath(), manifestText.toString().getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
Logger.error("Static manifest not written: " + manifestFile.getAbsolutePath() + ": " + e);
|
||||
return movedEntries.size();
|
||||
}
|
||||
|
||||
Logger.info("Static manifest: " + entries.size() + " static IDs written to " + manifestFile.getName());
|
||||
|
||||
return movedEntries.size();
|
||||
}
|
||||
|
||||
// A renumber file is deleted by hand once its SQL ran; until then the DB still holds the old IDs.
|
||||
public static boolean isRenumberPending(int mapID) {
|
||||
return new File(mapPath + mapID + ".renumber.sql").exists();
|
||||
}
|
||||
|
||||
// static_renumber_map: old ID -> new ID per moved key, read by World-Boot-Plan sql/static_renumber.sql.
|
||||
private static void writeRenumber(int mapID, ArrayList<ManifestEntry[]> movedEntries) {
|
||||
|
||||
File renumberFile = new File(mapPath + mapID + ".renumber.sql");
|
||||
StringBuilder sql = new StringBuilder();
|
||||
ManifestEntry previousEntry;
|
||||
ManifestEntry currentEntry;
|
||||
|
||||
sql.append("-- Static IDs that moved since the previous manifest of map ").append(mapID).append(".\n");
|
||||
sql.append("DROP TABLE IF EXISTS `static_renumber_map`;\n");
|
||||
sql.append("CREATE TABLE `static_renumber_map` (`oldID` INT NOT NULL, `newID` INT NOT NULL, `type` VARCHAR(32) NOT NULL, ")
|
||||
.append("`staticKey` VARCHAR(64) NOT NULL, PRIMARY KEY (`oldID`));\n");
|
||||
|
||||
for (int i = 0; i < movedEntries.size(); i++) {
|
||||
|
||||
previousEntry = movedEntries.get(i)[0];
|
||||
currentEntry = movedEntries.get(i)[1];
|
||||
|
||||
if (i % 500 == 0)
|
||||
sql.append("INSERT INTO `static_renumber_map` VALUES\n");
|
||||
|
||||
sql.append("(").append(previousEntry.id).append(", ").append(currentEntry.id).append(", '")
|
||||
.append(currentEntry.type).append("', '").append(currentEntry.key).append("')");
|
||||
sql.append(i % 500 == 499 || i == movedEntries.size() - 1 ? ";\n" : ",\n");
|
||||
}
|
||||
|
||||
try {
|
||||
Files.write(renumberFile.toPath(), sql.toString().getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
Logger.error("Static renumber mapping not written: " + renumberFile.getAbsolutePath() + ": " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.warn("Static manifest: " + movedEntries.size() + " moved IDs written to " + renumberFile.getName());
|
||||
}
|
||||
|
||||
// Logs every negative DB reference (below -1, which means "none") that no loaded static object of the right type holds.
|
||||
|
||||
public static void logOrphanReferences() {
|
||||
|
||||
HashMap<Integer, Integer> negativeValues;
|
||||
ManifestEntry entry;
|
||||
String expectedType;
|
||||
String problem;
|
||||
int orphanColumns = 0;
|
||||
int orphanRows = 0;
|
||||
|
||||
for (String[] referenceColumn : referenceColumns) {
|
||||
|
||||
expectedType = referenceColumn[2];
|
||||
negativeValues = DbManager.StaticWorldQueries.GET_NEGATIVE_REFERENCES(referenceColumn[0], referenceColumn[1]);
|
||||
|
||||
if (negativeValues == null)
|
||||
continue;
|
||||
|
||||
for (Map.Entry<Integer, Integer> negativeValue : negativeValues.entrySet()) {
|
||||
|
||||
entry = entriesByID.get(negativeValue.getKey());
|
||||
|
||||
if (entry == null)
|
||||
problem = "no static object";
|
||||
else if (DbManager.getFromCache(GameObjectType.valueOf(entry.type), entry.id) == null)
|
||||
problem = entry.type + " " + entry.key + " is not loaded";
|
||||
else if (expectedType != null && !expectedType.equals(entry.type))
|
||||
problem = "points at " + entry.type + " " + entry.key + ", expected " + expectedType;
|
||||
else
|
||||
continue;
|
||||
|
||||
Logger.warn("Orphan reference: " + referenceColumn[0] + "." + referenceColumn[1] + " = "
|
||||
+ negativeValue.getKey() + " on " + negativeValue.getValue() + " rows: " + problem);
|
||||
orphanColumns++;
|
||||
orphanRows += negativeValue.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
Logger.info("Static orphan check: " + orphanColumns + " orphan values on " + orphanRows + " rows");
|
||||
}
|
||||
|
||||
private static HashMap<String, ManifestEntry> readManifest(File manifestFile, int mapID) {
|
||||
|
||||
HashMap<String, ManifestEntry> previousByKey = new HashMap<>();
|
||||
JSONObject manifestJson;
|
||||
JSONArray staticsJson;
|
||||
JSONObject entryJson;
|
||||
|
||||
if (!manifestFile.exists()) {
|
||||
Logger.info("Static manifest: no previous " + manifestFile.getName() + ", nothing to diff");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
manifestJson = CacheParserUtil.readJsonFile(manifestFile);
|
||||
|
||||
if (manifestJson.getInt("map") != mapID) {
|
||||
Logger.error(manifestFile.getName() + ": map " + manifestJson.getInt("map") + " does not match MB_WORLD_MAPID " + mapID);
|
||||
return null;
|
||||
}
|
||||
|
||||
staticsJson = manifestJson.getJSONArray("statics");
|
||||
|
||||
for (int i = 0; i < staticsJson.length(); i++) {
|
||||
entryJson = staticsJson.getJSONObject(i);
|
||||
previousByKey.put(entryJson.getString("key"),
|
||||
new ManifestEntry(entryJson.getInt("id"), entryJson.getString("type"), entryJson.getString("key")));
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error("Previous static manifest unreadable, nothing to diff: " + manifestFile.getName() + ": " + e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return previousByKey;
|
||||
}
|
||||
|
||||
// A re-targeted ID is the dangerous case: player references to it now silently point at a different object.
|
||||
|
||||
private static void diffManifest(HashMap<String, ManifestEntry> previousByKey, ArrayList<ManifestEntry[]> movedEntries) {
|
||||
|
||||
HashMap<Integer, ManifestEntry> previousByID = new HashMap<>();
|
||||
ManifestEntry currentEntry;
|
||||
ManifestEntry previousEntry;
|
||||
int moved = 0;
|
||||
int vanished = 0;
|
||||
int retargeted = 0;
|
||||
int added = 0;
|
||||
|
||||
for (ManifestEntry entry : previousByKey.values())
|
||||
previousByID.put(entry.id, entry);
|
||||
|
||||
for (ManifestEntry entry : previousByKey.values()) {
|
||||
|
||||
currentEntry = entriesByKey.get(entry.key);
|
||||
|
||||
if (currentEntry == null) {
|
||||
Logger.warn("Static manifest: " + entry.type + " " + entry.key + " (was " + entry.id + ") vanished");
|
||||
vanished++;
|
||||
} else if (currentEntry.id != entry.id) {
|
||||
|
||||
if (moved < LOGGED_MOVES)
|
||||
Logger.warn("Static manifest: " + entry.type + " " + entry.key + " moved " + entry.id + " -> " + currentEntry.id);
|
||||
|
||||
movedEntries.add(new ManifestEntry[]{entry, currentEntry});
|
||||
moved++;
|
||||
}
|
||||
}
|
||||
|
||||
for (ManifestEntry entry : entries) {
|
||||
|
||||
previousEntry = previousByID.get(entry.id);
|
||||
|
||||
if (!previousByKey.containsKey(entry.key))
|
||||
added++;
|
||||
|
||||
if (previousEntry != null && !previousEntry.key.equals(entry.key)) {
|
||||
|
||||
if (retargeted < LOGGED_MOVES)
|
||||
Logger.warn("Static manifest: ID " + entry.id + " re-targeted from " + previousEntry.type + " "
|
||||
+ previousEntry.key + " to " + entry.type + " " + entry.key);
|
||||
|
||||
retargeted++;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.info("Static manifest diff: " + moved + " moved, " + vanished + " vanished, " + retargeted
|
||||
+ " re-targeted, " + added + " new");
|
||||
}
|
||||
|
||||
private static class ManifestEntry {
|
||||
|
||||
private final int id;
|
||||
private final String type;
|
||||
private final String key;
|
||||
|
||||
private ManifestEntry(int id, String type, String key) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
private String toJson() {
|
||||
return "{\"id\": " + id + ", \"type\": " + JSONObject.quote(type) + ", \"key\": " + JSONObject.quote(key) + "}";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,10 @@ import engine.mbEnums;
|
||||
import engine.objects.Building;
|
||||
import engine.objects.City;
|
||||
import engine.objects.Zone;
|
||||
import engine.objects.ZoneTemplate;
|
||||
import engine.parsers.map.ZoneTreeParser;
|
||||
import engine.parsers.objects.CZoneProp;
|
||||
import engine.parsers.objects.CZoneTemplate;
|
||||
import engine.parsers.objects.ZoneTreeEntry;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -36,7 +39,11 @@ public enum ZoneManager {
|
||||
|
||||
ZONEMANAGER;
|
||||
|
||||
public static HashMap<Integer, ZoneTemplate> _zone_templates = new HashMap<>();
|
||||
public static HashMap<Integer, CZoneTemplate> _zone_templates = new HashMap<>();
|
||||
public static ArrayList<ZoneTreeEntry> zoneTree;
|
||||
public static final HashMap<Integer, Zone> staticZonesByTreeUID = new HashMap<>();
|
||||
public static final HashMap<Integer, Integer> staticIDsByTreeUID = new HashMap<>();
|
||||
public static final ArrayList<Zone> ruinZones = new ArrayList<>();
|
||||
|
||||
public static final Set<Zone> macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
private static final ConcurrentHashMap<Integer, Zone> zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD);
|
||||
@@ -51,6 +58,89 @@ public enum ZoneManager {
|
||||
/* Instance variables */
|
||||
public static Zone seaFloor = null;
|
||||
|
||||
// CZONE templates plus the server's player-city template 0, which has no CZONE file
|
||||
|
||||
public static void loadZoneTemplates() {
|
||||
|
||||
CZoneTemplate playerCityTemplate = new CZoneTemplate();
|
||||
|
||||
_zone_templates.putAll(CZoneTemplate._zones);
|
||||
|
||||
playerCityTemplate.template_id = 0;
|
||||
playerCityTemplate.zone_sea_level_type = mbEnums.SeaLevelType.PARENT;
|
||||
playerCityTemplate.zone_sea_level = 0;
|
||||
playerCityTemplate.zone_max_blend = 128;
|
||||
playerCityTemplate.zone_min_blend = 128;
|
||||
playerCityTemplate.terrain_max_y = 5;
|
||||
playerCityTemplate.zone_major_radius = (int) mbEnums.CityBoundsType.ZONE.halfExtents;
|
||||
playerCityTemplate.zone_minor_radius = (int) mbEnums.CityBoundsType.ZONE.halfExtents;
|
||||
playerCityTemplate.terrain_type = mbEnums.TerrainGenType.PLANAR;
|
||||
|
||||
_zone_templates.put(playerCityTemplate.template_id, playerCityTemplate);
|
||||
|
||||
Logger.info("Zone templates: " + _zone_templates.size());
|
||||
}
|
||||
|
||||
// Read before the zone templates, so only the templates this map uses are parsed. False aborts boot.
|
||||
|
||||
public static boolean loadZoneTree(int mapID) {
|
||||
|
||||
zoneTree = ZoneTreeParser.parseZoneTree(mapID);
|
||||
|
||||
return zoneTree != null;
|
||||
}
|
||||
|
||||
public static TreeSet<Integer> getZoneTreeTemplateIDs() {
|
||||
|
||||
TreeSet<Integer> templateIDs = new TreeSet<>();
|
||||
|
||||
for (ZoneTreeEntry treeEntry : zoneTree)
|
||||
templateIDs.add(treeEntry.template);
|
||||
|
||||
return templateIDs;
|
||||
}
|
||||
|
||||
// Static zones from the map's zone tree, then player-city zones from the DB. Every static zone takes its
|
||||
// static ID in tree order (W10); zones use it as their ID only once static buildings load from JSON (2.4).
|
||||
// False aborts boot.
|
||||
|
||||
public static boolean loadZones(boolean useStaticIDs) {
|
||||
|
||||
ArrayList<Zone> cityZones;
|
||||
Zone zone;
|
||||
int staticID;
|
||||
int parentZoneID;
|
||||
int staticCount = 0;
|
||||
|
||||
for (ZoneTreeEntry treeEntry : zoneTree) {
|
||||
|
||||
if (treeEntry.parent != 0 && !staticZonesByTreeUID.containsKey(treeEntry.parent)) {
|
||||
Logger.error("Zone " + treeEntry.uid + " (" + treeEntry.name + ") has no parent zone " + treeEntry.parent);
|
||||
return false;
|
||||
}
|
||||
|
||||
staticID = DbManager.nextStaticID(mbEnums.GameObjectType.Zone, "zone:" + treeEntry.uid);
|
||||
staticIDsByTreeUID.put(treeEntry.uid, staticID);
|
||||
|
||||
if (treeEntry.parent == 0)
|
||||
parentZoneID = 0;
|
||||
else
|
||||
parentZoneID = staticZonesByTreeUID.get(treeEntry.parent).getObjectUUID();
|
||||
|
||||
zone = Zone.createStaticZone(treeEntry, useStaticIDs ? staticID : treeEntry.uid, parentZoneID);
|
||||
DbManager.addToCache(zone);
|
||||
zone.runAfterLoad();
|
||||
staticZonesByTreeUID.put(treeEntry.uid, zone);
|
||||
staticCount++;
|
||||
}
|
||||
|
||||
cityZones = DbManager.ZoneQueries.GET_PLAYER_CITY_ZONES();
|
||||
|
||||
Logger.info("Zones: " + staticCount + " static, " + cityZones.size() + " player city");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find all zones coordinates fit into, starting with Sea Floor
|
||||
|
||||
public static ArrayList<Zone> getAllZonesIn(final Vector3fImmutable loc) {
|
||||
@@ -139,6 +229,46 @@ public enum ZoneManager {
|
||||
return ZoneManager.zonesByName.get(zoneName);
|
||||
}
|
||||
|
||||
// Ruins: static zones whose top-level CITY props carry a seed ruin key (the 8 Ruins on map 108). Needs the guild seed.
|
||||
public static void loadRuinZones() {
|
||||
|
||||
Zone zone;
|
||||
|
||||
for (ZoneTreeEntry treeEntry : ZoneManager.zoneTree) {
|
||||
|
||||
zone = ZoneManager.staticZonesByTreeUID.get(treeEntry.uid);
|
||||
|
||||
for (CZoneProp prop : zone.template.zone_prop_info)
|
||||
if (prop.prop_type == mbEnums.ZonePropType.CITY && GuildManager._ruinKeys.contains(prop.city_prop_gm_guild)) {
|
||||
ZoneManager.ruinZones.add(zone);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.info("Ruins: " + ZoneManager.ruinZones.size() + " zones" + (ConfigManager.MB_USE_RUINS.getValue().equalsIgnoreCase("true")
|
||||
? "" : " (MB_USE_RUINS off: respawn at Sea Dog's Rest)"));
|
||||
}
|
||||
|
||||
// Respawn point of a character with no usable bind: a random Ruin, or Sea Dog's Rest when ruins are off or missing.
|
||||
public static Vector3fImmutable getRandomRuinLocation() {
|
||||
|
||||
Zone ruinZone;
|
||||
|
||||
if (ConfigManager.MB_USE_RUINS.getValue().equalsIgnoreCase("true") && !ZoneManager.ruinZones.isEmpty()) {
|
||||
ruinZone = ZoneManager.ruinZones.get(ThreadLocalRandom.current().nextInt(ZoneManager.ruinZones.size()));
|
||||
return Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
|
||||
}
|
||||
|
||||
ruinZone = ZoneManager.getZoneByName("sea dog's rest");
|
||||
|
||||
// 14001 does not have a banestone to bind at
|
||||
|
||||
if (ruinZone.templateID == 14001)
|
||||
return Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
|
||||
|
||||
return Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc().add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
|
||||
}
|
||||
|
||||
public static Collection<Zone> getAllZones() {
|
||||
return ZoneManager.zonesByUUID.values();
|
||||
}
|
||||
|
||||
@@ -82,11 +82,7 @@ public class ChantJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
if (AbstractWorldObject.IsAbstractCharacter(source))
|
||||
//handle invul
|
||||
if (power.getUUID() != 334)
|
||||
((AbstractCharacter) this.source).setLastChant((int) (this.power.getChantDuration()) * 1000, this);
|
||||
else
|
||||
((AbstractCharacter) this.source).setLastChant((int) (this.power.getChantDuration()) * 1000, this);
|
||||
((AbstractCharacter) this.source).setLastChant((int) (this.power.getChantDuration()) * 1000, this);
|
||||
} else {
|
||||
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
|
||||
if (AbstractWorldObject.IsAbstractCharacter(source)) {
|
||||
|
||||
@@ -25,6 +25,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
private final DamageOverTimePowerAction dot;
|
||||
private int iteration = 0;
|
||||
private int liveCounter = 0;
|
||||
private final int tickLength;
|
||||
|
||||
public DamageOverTimeJob(AbstractWorldObject source, AbstractWorldObject target, String stackType, int trains, ActionsBase action, PowersBase power, EffectsBase eb, DamageOverTimePowerAction dot) {
|
||||
super(source, target, stackType, trains, action, power, eb);
|
||||
@@ -33,7 +34,9 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
if (this.target != null && AbstractWorldObject.IsAbstractCharacter(target))
|
||||
this.liveCounter = ((AbstractCharacter) target).getLiveCounter();
|
||||
|
||||
this.iteration = action.getDurationInSeconds(trains) / this.dot.getNumIterations();
|
||||
// PowerActions.cfg gives the tick count; the ticks split the action's duration
|
||||
this.iteration = this.dot.getNumIterations();
|
||||
this.tickLength = action.getDuration(trains) / Math.max(1, this.dot.getNumIterations());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +85,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
public int getTickLength() {
|
||||
return this.dot.getNumIterations() * 1000;
|
||||
return this.tickLength;
|
||||
}
|
||||
|
||||
public int inc() {
|
||||
|
||||
@@ -21,11 +21,15 @@ public class TransferStatOTJob extends AbstractEffectJob {
|
||||
|
||||
private final TransferStatOTPowerAction dot;
|
||||
private int iteration = 0;
|
||||
private final int tickLength;
|
||||
|
||||
public TransferStatOTJob(AbstractWorldObject source, AbstractWorldObject target, String stackType, int trains, ActionsBase action, PowersBase power, EffectsBase eb, TransferStatOTPowerAction dot) {
|
||||
super(source, target, stackType, trains, action, power, eb);
|
||||
this.dot = dot;
|
||||
this.iteration = action.getDurationInSeconds(trains) / this.dot.getNumIterations();
|
||||
|
||||
// PowerActions.cfg gives the tick count; the ticks split the action's duration
|
||||
this.iteration = this.dot.getNumIterations();
|
||||
this.tickLength = action.getDuration(trains) / Math.max(1, this.dot.getNumIterations());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,7 +68,7 @@ public class TransferStatOTJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
public int getTickLength() {
|
||||
return this.dot.getNumIterations() * 1000;
|
||||
return this.tickLength;
|
||||
}
|
||||
|
||||
public int inc() {
|
||||
|
||||
@@ -12,9 +12,9 @@ import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ForgeManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.NPC;
|
||||
import engine.objects.Warehouse;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -127,16 +127,16 @@ public class WorkOrder implements Delayed {
|
||||
|
||||
int validation_result = 0;
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID);
|
||||
|
||||
if (workOrder.vendor.getBuilding() == null)
|
||||
return 58; //58: The formula is beyond the means of this facility
|
||||
|
||||
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.item_wt))
|
||||
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.getItemWt()))
|
||||
return 30; //30: That person cannot carry that item
|
||||
|
||||
if ((workOrder.prefixToken != 0 || workOrder.suffixToken != 0) &&
|
||||
!workOrder.vendor.getItemModTable().contains((template.modTable)))
|
||||
!workOrder.vendor.getItemModTable().contains(ForgeManager.getVendorModTable(workOrder.templateID)))
|
||||
return 59; //59: This hireling does not have this formula
|
||||
|
||||
if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
|
||||
|
||||
@@ -408,7 +408,7 @@ public class Bounds {
|
||||
|
||||
blueprint = building.getBlueprint();
|
||||
|
||||
this.quaternion = new Quaternion(building.getRot().x, building.getRot().y, building.getRot().z, building.getw());
|
||||
this.quaternion = new Quaternion(building.getRotation().x, building.getRotation().y, building.getRotation().z, building.getRotation().w);
|
||||
|
||||
// Calculate Bounds for non-blueprint objects
|
||||
|
||||
@@ -437,7 +437,7 @@ public class Bounds {
|
||||
|
||||
// The rotation is reset after the new aabb is calculated.
|
||||
|
||||
this.rotation = building.getRot().y;
|
||||
this.rotation = building.getRotation().y;
|
||||
|
||||
// Caclculate and set the new half halfExtents for the rotated bounding box
|
||||
// and reset the rotation to 0 for this bounds.
|
||||
@@ -451,7 +451,7 @@ public class Bounds {
|
||||
}
|
||||
|
||||
this.origin.set(building.getLoc().x, building.getLoc().z);
|
||||
this.rotation = building.getRot().y;
|
||||
this.rotation = building.getRotation().y;
|
||||
this.halfExtents.set(blueprint.getExtents());
|
||||
this.flipExtents = Bounds.calculateFlipExtents(this);
|
||||
|
||||
|
||||
@@ -583,36 +583,6 @@ final public class FastMath {
|
||||
return ret.normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a String into an Integer hash that the client will recognize.
|
||||
*
|
||||
* @param s The String to hash
|
||||
* @return the Integer hash
|
||||
*/
|
||||
public static int hash(String s) {
|
||||
int out = 0, pad = 0;
|
||||
for (char c : s.toCharArray()) {
|
||||
if (c == ' ' || c == '\\') {
|
||||
pad += 5;
|
||||
continue;
|
||||
}
|
||||
if (c > 0x40 && c < 0x60)
|
||||
out ^= _rotl((byte) 0x60, pad);
|
||||
out ^= _rotl((byte) (c & 0xDF), pad);
|
||||
pad += 5;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function for making hashes
|
||||
*/
|
||||
private static int _rotl(int value, int shift) {
|
||||
if ((shift &= 31) == 0)
|
||||
return value;
|
||||
return (value << shift) | (value >> (32 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of seconds until next hours
|
||||
*/
|
||||
|
||||
@@ -1142,6 +1142,17 @@ public class Quaternion {
|
||||
return opposite(this);
|
||||
}
|
||||
|
||||
// Client MakeRotateY (Math.dll 0x10002960): w = cos θ/2, y = sin θ/2, radians.
|
||||
// Math rather than FastMath: FastMath.reduceSinAngle mis-reduces angles below -π.
|
||||
public static Quaternion fromYaw(float yaw) {
|
||||
return new Quaternion(0f, (float) Math.sin(yaw * 0.5), 0f, (float) Math.cos(yaw * 0.5));
|
||||
}
|
||||
|
||||
// The angle MakeRotateY would need to produce this rotation; characters send it as one float.
|
||||
public float getYaw() {
|
||||
return 2 * FastMath.atan2(y, w);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Quaternion clone() {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.math;
|
||||
|
||||
// The client's placement (ArcObjectInfo +0x28/+0x34/+0x44, math::Transformation); see MBDATA/specs/WorldPlacement.md §7.
|
||||
|
||||
public class Transform {
|
||||
|
||||
public final Vector3fImmutable location;
|
||||
public final Quaternion rotation;
|
||||
public final Vector3f scale;
|
||||
|
||||
public Transform(Vector3fImmutable location, Quaternion rotation, Vector3f scale) {
|
||||
this.location = location;
|
||||
this.rotation = rotation;
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public static Transform fromYaw(Vector3fImmutable location, float yaw) {
|
||||
return new Transform(location, Quaternion.fromYaw(yaw), new Vector3f(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
// world = parent × local, as the client composes zone and object transforms (sb.exe 0x6516C0).
|
||||
public static Transform mult(Transform parent, Transform local) {
|
||||
|
||||
Vector3f scaledLocation;
|
||||
Vector3f rotatedLocation;
|
||||
Quaternion rotation;
|
||||
Vector3f scale;
|
||||
|
||||
scaledLocation = new Vector3f(local.location).mult(parent.scale);
|
||||
rotatedLocation = parent.rotation.mult(scaledLocation);
|
||||
rotation = parent.rotation.mult(local.rotation);
|
||||
scale = parent.scale.mult(local.scale);
|
||||
|
||||
return new Transform(parent.location.add(rotatedLocation), rotation, scale);
|
||||
}
|
||||
|
||||
}
|
||||
+162
-100
@@ -8,24 +8,19 @@
|
||||
|
||||
package engine;
|
||||
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector2f;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.Shrine;
|
||||
import engine.objects.Zone;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.RunePowerEntry;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/*
|
||||
* MagicBane engine enumeration class.
|
||||
@@ -504,61 +499,6 @@ public class mbEnums {
|
||||
|
||||
}
|
||||
|
||||
public enum Ruins {
|
||||
|
||||
ESTRAGOTH(569),
|
||||
KARFELL(570),
|
||||
MORELAN(571),
|
||||
REGARS(572),
|
||||
HALLOS(573),
|
||||
WESTERMORE(574),
|
||||
EYWAN(575),
|
||||
CAER(576);
|
||||
|
||||
private final int zoneUUID;
|
||||
|
||||
Ruins(int uuid) {
|
||||
this.zoneUUID = uuid;
|
||||
}
|
||||
|
||||
public static Ruins getRandomRuin() {
|
||||
|
||||
Ruins ruins;
|
||||
|
||||
ruins = Ruins.values()[ThreadLocalRandom.current()
|
||||
.nextInt(Ruins.values().length)];
|
||||
|
||||
return ruins;
|
||||
}
|
||||
|
||||
public Vector3fImmutable getLocation() {
|
||||
|
||||
Zone ruinZone;
|
||||
Vector3fImmutable spawnLocation;
|
||||
|
||||
// Send to SDR if so configured
|
||||
|
||||
if (ConfigManager.MB_USE_RUINS.getValue().equalsIgnoreCase("true")) {
|
||||
ruinZone = ZoneManager.getZoneByUUID(this.zoneUUID);
|
||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
|
||||
} else {
|
||||
ruinZone = ZoneManager.getZoneByName("sea dog's rest");
|
||||
|
||||
// 14001 does not have a banestone to bind at
|
||||
|
||||
if (ruinZone.templateID == 14001)
|
||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
|
||||
else
|
||||
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
|
||||
.add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
|
||||
}
|
||||
|
||||
|
||||
return spawnLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum Guards {
|
||||
|
||||
HumanArcher(13.97f, 13.97f, 6.19f, 4.2199998f, 18.38f, 6.33f, 6.5f),
|
||||
@@ -824,6 +764,7 @@ public class mbEnums {
|
||||
ACID,
|
||||
DISEASE,
|
||||
UNKNOWN,
|
||||
ANTISIEGE,
|
||||
// these added for immunities
|
||||
ATTACK,
|
||||
POWERS,
|
||||
@@ -842,34 +783,26 @@ public class mbEnums {
|
||||
|
||||
public static DamageType getDamageType(String modName) {
|
||||
|
||||
String name;
|
||||
|
||||
if (modName.isEmpty())
|
||||
return DamageType.NONE;
|
||||
|
||||
if(modName.toLowerCase().equals("blind"))
|
||||
modName = "BLINDNESS";
|
||||
// Client and DB strings vary in case and punctuation ("Fire", "Anti-Siege")
|
||||
|
||||
if(modName.toLowerCase().equals("powerblock"))
|
||||
modName = "POWERINHIBITOR";
|
||||
name = modName.replaceAll("[\\s,-]", "").toUpperCase();
|
||||
|
||||
//validity check for not looking up damage type that doesn't exist
|
||||
boolean valid = false;
|
||||
for(DamageType type : DamageType.values()){
|
||||
if(type.name().equals(modName))
|
||||
valid = true;
|
||||
}
|
||||
if (name.equals("BLIND"))
|
||||
name = "BLINDNESS";
|
||||
|
||||
if(!valid)
|
||||
return DamageType.NONE;
|
||||
if (name.equals("POWERBLOCK"))
|
||||
name = "POWERINHIBITOR";
|
||||
|
||||
DamageType damageType;
|
||||
for (DamageType type : DamageType.values())
|
||||
if (type.name().equals(name))
|
||||
return type;
|
||||
|
||||
try {
|
||||
damageType = DamageType.valueOf(modName.replace(",", "").toUpperCase());
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
return DamageType.NONE;
|
||||
}
|
||||
return damageType;
|
||||
return DamageType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,11 +1037,28 @@ public class mbEnums {
|
||||
|
||||
public static EffectSourceType GetEffectSourceType(String modName) {
|
||||
EffectSourceType returnMod;
|
||||
String name;
|
||||
|
||||
if (modName.isEmpty())
|
||||
return EffectSourceType.None;
|
||||
|
||||
name = modName.replace(",", "").replace("-", "").trim();
|
||||
|
||||
// Effects.cfg SOURCE blocks use the short damage names
|
||||
switch (name) {
|
||||
case "Crush":
|
||||
name = "Crushing";
|
||||
break;
|
||||
case "Pierce":
|
||||
name = "Piercing";
|
||||
break;
|
||||
case "Slash":
|
||||
name = "Slashing";
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
returnMod = EffectSourceType.valueOf(modName.replace(",", ""));
|
||||
returnMod = EffectSourceType.valueOf(name);
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
return EffectSourceType.None;
|
||||
@@ -1138,6 +1088,7 @@ public class mbEnums {
|
||||
BMHealing,
|
||||
Charm,
|
||||
ClassBoon,
|
||||
ColdDeBuff,
|
||||
Confusion,
|
||||
DamageAbsorber,
|
||||
DamageDebuff,
|
||||
@@ -1152,6 +1103,7 @@ public class mbEnums {
|
||||
ElementalDeBuff,
|
||||
EnchantWeapon,
|
||||
Fear,
|
||||
FireDeBuff,
|
||||
Flight,
|
||||
Frenzy,
|
||||
GroupHeal,
|
||||
@@ -1159,12 +1111,16 @@ public class mbEnums {
|
||||
HealOverTime,
|
||||
HealResBuff,
|
||||
HealthPotion,
|
||||
HolyDeBuff,
|
||||
IgnoreStack,
|
||||
Invisible,
|
||||
LightningDeBuff,
|
||||
MagicDeBuff,
|
||||
ManaPotion,
|
||||
MangonelFire,
|
||||
MeleeDamageDeBuff,
|
||||
MeleeDeBuff,
|
||||
MentalDeBuff,
|
||||
MoveBuff,
|
||||
MoveDebuff,
|
||||
NoFear,
|
||||
@@ -1177,6 +1133,9 @@ public class mbEnums {
|
||||
NoTrack,
|
||||
PassiveDefense,
|
||||
PersAttrSPRBuff,
|
||||
PersonalAttrCONBuff,
|
||||
PersonalAttrDEXBuff,
|
||||
PersonalAttrSTRBuff,
|
||||
PetBuff,
|
||||
PierceResistanceDebuff,
|
||||
PoisonBuchinine,
|
||||
@@ -1199,7 +1158,6 @@ public class mbEnums {
|
||||
RecoveryStaminaDeBuff,
|
||||
ResistanceBuff,
|
||||
ResistanceDeBuff,
|
||||
ResistanceDebuff,
|
||||
Root,
|
||||
SafeMode,
|
||||
SelfOneAttrBuff,
|
||||
@@ -1223,6 +1181,7 @@ public class mbEnums {
|
||||
Stun,
|
||||
Track,
|
||||
Transform,
|
||||
UnholyDeBuff,
|
||||
WeaponMove;
|
||||
|
||||
public static StackType GetStackType(String modName) {
|
||||
@@ -1509,6 +1468,15 @@ public class mbEnums {
|
||||
}
|
||||
}
|
||||
|
||||
// rune_type values from the client cache data (COBJECTS/RUNE)
|
||||
|
||||
public enum RuneType {
|
||||
CLASS,
|
||||
DISCIPLINE,
|
||||
RACE,
|
||||
TALENT
|
||||
}
|
||||
|
||||
public enum ShrineType {
|
||||
|
||||
Aelfborn(1701900, -75506007, true),
|
||||
@@ -2632,55 +2600,61 @@ public class mbEnums {
|
||||
|
||||
public enum MinionType {
|
||||
AELFBORNGUARD(951, 1637, MinionClass.MELEE, "Guard", "Aelfborn"),
|
||||
AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn"),
|
||||
AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn", "WIZ-016", "WIZ-061", "WIZ-025", "WIZ-020"),
|
||||
AMAZONGUARD(1500, 1670, MinionClass.MELEE, "Guard", "Amazon"),
|
||||
AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon"),
|
||||
AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon", "FUR-003", "FUR-011", "FUR-009", "FUR-005"),
|
||||
ARACOIXGUARD(1600, 1672, MinionClass.MELEE, "Guard", "Aracoix"), //used guard captain equipset.
|
||||
ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix"),
|
||||
ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix", "WLR-029", "WLR-019", "WLR-027", "WLR-012"),
|
||||
CENTAURGUARD(1650, 1642, MinionClass.MELEE, "Guard", "Centaur"),
|
||||
CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur"),
|
||||
CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur", "PRL-017", "PRL-046", "PRL-033", "PRL-009"),
|
||||
DWARVENARCHER(845, 1644, MinionClass.ARCHER, "Marksman", "Dwarven"),
|
||||
DWARVENGUARD(1050, 1666, MinionClass.MELEE, "Guard", "Dwarven"),
|
||||
DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven"),
|
||||
DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven", "PRL-017", "PRL-046", "PRL-033", "PRL-009"),
|
||||
ELFGUARD(1180, 1671, MinionClass.MELEE, "Guard", "Elven"), //old 1645
|
||||
ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven"),
|
||||
ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven", "WIZ-020", "WIZ-025", "WIZ-016", "WIZ-061"),
|
||||
FORESTGUARD(1550, 1668, MinionClass.MELEE, "Guard", "Forest"), //captain changed to guard equipset
|
||||
FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest"),
|
||||
FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest", "DRU-009", "DRU-023", "DRU-036", "DRU-015"),
|
||||
HOLYGUARD(1525, 1658, MinionClass.MELEE, "Guard", "Holy Church"),
|
||||
HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church"),
|
||||
HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church", "PRL-017", "PRL-046", "PRL-033", "PRL-009"),
|
||||
HUMANARCHER(846, 1654, MinionClass.ARCHER, "Archer", "Human"),
|
||||
HUMANGUARD(840, 1665, MinionClass.MELEE, "Guard", "Human"),
|
||||
HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human"),
|
||||
HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human", "WIZ-016", "WIZ-025", "WIZ-020", "WIZ-061"),
|
||||
IREKEIGUARD(1350, 1659, MinionClass.MELEE, "Guard", "Irekei"),
|
||||
IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei"),
|
||||
IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"),
|
||||
MINOTAURARCHER(1701, 0, MinionClass.ARCHER, "Archer", "Minotaur"),
|
||||
MINOTAURGUARD(1700, 1673, MinionClass.MELEE, "Guard", "Minotaur"),
|
||||
NORTHMANGUARD(1250, 1669, MinionClass.MELEE, "Guard", "Northman"),
|
||||
NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman"),
|
||||
NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"),
|
||||
SHADEGUARD(1450, 1662, MinionClass.MELEE, "Guard", "Shade"),
|
||||
SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade"),
|
||||
SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade", "NEC-001", "NEC-003", "MAG-013", "MAG-025"),
|
||||
TEMPLARGUARD(841, 1564, MinionClass.MELEE, "Marksman", "Templar"),
|
||||
TEMPLEGUARD(1575, 1652, MinionClass.MELEE, "Guard", "Temple"),
|
||||
TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple"),
|
||||
TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple", "CON-048", "CON-015", "CON-012", "CON-051"),
|
||||
UNDEADGUARD(980100, 1674, MinionClass.MELEE, "Guard", "Undead"),
|
||||
UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead"),
|
||||
UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead", "NEC-001", "NEC-003", "MAG-013", "MAG-025"),
|
||||
WEREWOLFGUARD(980104, 0, MinionClass.MELEE, "Guard", "Werewolf"),
|
||||
WEREBEARGUARD(980103, 0, MinionClass.MELEE, "Guard", "Werebear");
|
||||
public static HashMap<Integer, MinionType> ContractToMinionMap = new HashMap<>();
|
||||
private static final int CAPTAIN_POWER_RANK = 40;
|
||||
private final int captainContractID;
|
||||
private final int equipSetID;
|
||||
private final MinionClass minionClass;
|
||||
private final String name;
|
||||
private final String race;
|
||||
private final ArrayList<RunePowerEntry> captainPowers;
|
||||
|
||||
MinionType(int captainContractID, int equipSetID, MinionClass minionClass, String name, String race) {
|
||||
// Captain powers were hand-made by the server team; no client rune or deed lists them
|
||||
MinionType(int captainContractID, int equipSetID, MinionClass minionClass, String name, String race, String... captainPowerTypes) {
|
||||
|
||||
this.captainContractID = captainContractID;
|
||||
this.equipSetID = equipSetID;
|
||||
this.minionClass = minionClass;
|
||||
this.name = name;
|
||||
this.race = race;
|
||||
this.captainPowers = new ArrayList<>();
|
||||
|
||||
for (String powerType : captainPowerTypes)
|
||||
this.captainPowers.add(new RunePowerEntry(race + " " + name, powerType, CAPTAIN_POWER_RANK));
|
||||
}
|
||||
|
||||
public static void InitializeMinions() {
|
||||
@@ -2689,6 +2663,17 @@ public class mbEnums {
|
||||
ContractToMinionMap.put(minionType.captainContractID, minionType);
|
||||
}
|
||||
|
||||
// The powers a guard captain's contract casts, shared by its minions; empty for non-caster contracts
|
||||
public static ArrayList<RunePowerEntry> getCaptainPowers(int captainContractID) {
|
||||
|
||||
MinionType minionType = ContractToMinionMap.get(captainContractID);
|
||||
|
||||
if (minionType == null)
|
||||
return new ArrayList<>();
|
||||
|
||||
return minionType.captainPowers;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -2761,7 +2746,6 @@ public class mbEnums {
|
||||
public static HashMap<Integer, ResourceType> templateHashLookup = new HashMap<>();
|
||||
public static HashMap<Integer, ResourceType> resourceHashLookup = new HashMap<>();
|
||||
public int templateID;
|
||||
public ItemTemplate template;
|
||||
public int resourceHash;
|
||||
public int templateHash;
|
||||
public int deposit_limit;
|
||||
@@ -2769,7 +2753,6 @@ public class mbEnums {
|
||||
|
||||
ResourceType(int templateID, int resourceHash, int templateHash, int deposit_limit, int mine_production) {
|
||||
this.templateID = templateID;
|
||||
this.template = ItemTemplate.templates.get(this.templateID);
|
||||
this.resourceHash = resourceHash;
|
||||
this.templateHash = templateHash;
|
||||
this.deposit_limit = deposit_limit;
|
||||
@@ -2908,6 +2891,14 @@ public class mbEnums {
|
||||
EMPTY_NEWITEM;
|
||||
}
|
||||
|
||||
// Cache JSON names. UNKNOWN is raw 0, which the client treats as no slot (sb.exe 0x4AC810).
|
||||
public enum SheathSlot {
|
||||
UNKNOWN,
|
||||
BACK,
|
||||
WAIST,
|
||||
NONE
|
||||
}
|
||||
|
||||
public enum AttributeType {
|
||||
None,
|
||||
Strength,
|
||||
@@ -3096,6 +3087,77 @@ public class mbEnums {
|
||||
MULTIPLY
|
||||
}
|
||||
|
||||
// CZONE value sets; only the values present in the shipped cache.
|
||||
|
||||
public enum ZoneShapeType {
|
||||
ELLIPTICAL,
|
||||
RECTANGULAR
|
||||
}
|
||||
|
||||
public enum SeaLevelType {
|
||||
PARENT,
|
||||
SELF,
|
||||
WORLD
|
||||
}
|
||||
|
||||
// NONE is the server's marker for a zone with no zone_terrain_gen block
|
||||
|
||||
public enum TerrainGenType {
|
||||
NONE,
|
||||
TARGA,
|
||||
PLANAR
|
||||
}
|
||||
|
||||
public enum ZonePropType {
|
||||
PROP,
|
||||
CITY
|
||||
}
|
||||
|
||||
public enum ZoneMobileType {
|
||||
MOBILE,
|
||||
TRAINER
|
||||
}
|
||||
|
||||
// MB_STATIC_BUILDINGS (World Boot Plan 2.4). DB: static buildings from obj_building, before the migration.
|
||||
// PARITY: DB load plus the JSON buildings compared and the migration mapping written. JSON: after the migration.
|
||||
public enum StaticBuildingMode {
|
||||
DB,
|
||||
PARITY,
|
||||
JSON;
|
||||
|
||||
public static StaticBuildingMode fromConfig(String configValue) {
|
||||
|
||||
for (StaticBuildingMode mode : values())
|
||||
if (mode.name().equalsIgnoreCase(configValue.trim()))
|
||||
return mode;
|
||||
|
||||
return DB;
|
||||
}
|
||||
}
|
||||
|
||||
// MB_STATIC_RUNEGATES (World Boot Plan 2.7). DB: static_runegate_portals. JSON: registry props and maps/<map>.gates,
|
||||
// which needs MB_STATIC_BUILDINGS=JSON. Required; null when missing or unknown, and boot aborts.
|
||||
public enum StaticRunegateMode {
|
||||
DB,
|
||||
JSON;
|
||||
|
||||
public static StaticRunegateMode fromConfig(String configValue) {
|
||||
|
||||
if (configValue == null)
|
||||
return null;
|
||||
|
||||
for (StaticRunegateMode mode : values())
|
||||
if (mode.name().equalsIgnoreCase(configValue.trim()))
|
||||
return mode;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public enum PointSetType {
|
||||
POINTS_ORDEREDREV
|
||||
}
|
||||
|
||||
public enum ServerConfig {
|
||||
MBDB_108("AERYNTH", "ARAC", "MOURNING", 300000),
|
||||
MBDB_192("DALGOTH", "ARAC", "GOOK", 300001),
|
||||
|
||||
@@ -19,6 +19,7 @@ import engine.mobileAI.Threads.ReSpawner;
|
||||
import engine.mobileAI.utilities.MovementUtilities;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.powers.ActionsBase;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.powers.RunePowerEntry;
|
||||
@@ -49,6 +50,8 @@ public class MobAI {
|
||||
|
||||
private static final boolean PET_AGGRO_ENABLED = false;
|
||||
|
||||
private static final int STANDING_GUARD_RUNE_ID = 252623;
|
||||
|
||||
private static void attackTarget(Mob mob, AbstractWorldObject target) {
|
||||
|
||||
try {
|
||||
@@ -276,7 +279,7 @@ public class MobAI {
|
||||
|
||||
// Mobile has no powers defined in mobbase or contract..
|
||||
|
||||
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && PowersManager.getPowersForRune(contractID).isEmpty())
|
||||
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && mbEnums.MinionType.getCaptainPowers(contractID).isEmpty())
|
||||
return false;
|
||||
|
||||
if (mob.nextCastTime == 0)
|
||||
@@ -309,18 +312,17 @@ public class MobAI {
|
||||
powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
|
||||
purgeEntries = new ArrayList<>();
|
||||
|
||||
// Additional powers may come from the contract ID. This is to support
|
||||
// powers for player guards irrespective of the mobbase used.
|
||||
// Player guards also cast their captain contract's powers, irrespective of the mobbase used.
|
||||
|
||||
if (mob.isPlayerGuard()) {
|
||||
|
||||
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
|
||||
|
||||
if (mob.contract != null)
|
||||
contractEntries = PowersManager.getPowersForRune(mob.contractUUID);
|
||||
contractEntries = mbEnums.MinionType.getCaptainPowers(mob.contractUUID);
|
||||
|
||||
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION))
|
||||
contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID);
|
||||
contractEntries = mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID);
|
||||
|
||||
powerEntries.addAll(contractEntries);
|
||||
|
||||
@@ -357,7 +359,7 @@ public class MobAI {
|
||||
int powerRank = runePowerEntry.rank;
|
||||
|
||||
if (mob.isPlayerGuard())
|
||||
powerRank = getGuardPowerRank(mob);
|
||||
powerRank = getGuardPowerRank(mob, mobPower);
|
||||
|
||||
// Cast the spell
|
||||
|
||||
@@ -387,33 +389,27 @@ public class MobAI {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getGuardPowerRank(Mob mob) {
|
||||
int powerRank = 1;
|
||||
// Client power rank adds every POWERSADJ step at or below the level (0x4B34B0). The Standing Guard rune's
|
||||
// Wizard steps are the curve for every captain spell, capped at MaxLevel as player casts are.
|
||||
public static int getGuardPowerRank(Mob mob, PowersBase power) {
|
||||
|
||||
switch (mob.getRank()) {
|
||||
case 1:
|
||||
powerRank = 10;
|
||||
break;
|
||||
case 2:
|
||||
powerRank = 15;
|
||||
break;
|
||||
case 3:
|
||||
powerRank = 20;
|
||||
break;
|
||||
case 4:
|
||||
powerRank = 25;
|
||||
break;
|
||||
case 5:
|
||||
powerRank = 30;
|
||||
break;
|
||||
case 6:
|
||||
powerRank = 35;
|
||||
break;
|
||||
case 7:
|
||||
powerRank = 40;
|
||||
break;
|
||||
}
|
||||
return powerRank;
|
||||
RuneTemplate guardRune = RuneTemplate._runes.get(STANDING_GUARD_RUNE_ID);
|
||||
ArrayList<int[]> rankSteps;
|
||||
int powerRank = 0;
|
||||
|
||||
if (guardRune == null || guardRune.item_power_action.isEmpty())
|
||||
return 1;
|
||||
|
||||
rankSteps = guardRune.item_power_action.get(power.getIDString());
|
||||
|
||||
if (rankSteps == null)
|
||||
rankSteps = guardRune.item_power_action.values().iterator().next();
|
||||
|
||||
for (int[] rankStep : rankSteps)
|
||||
if (rankStep[1] <= mob.getLevel())
|
||||
powerRank += rankStep[0];
|
||||
|
||||
return Math.max(1, Math.min(powerRank, power.getMaxTrains()));
|
||||
}
|
||||
|
||||
public static void mobCallForHelp(Mob mob) {
|
||||
@@ -470,7 +466,7 @@ public class MobAI {
|
||||
|
||||
//trebuchet spawn handler
|
||||
|
||||
if (mob.despawned && mob.getMobBase().getLoadID() == 13171) {
|
||||
if (mob.despawned && mob.getMobBase().getObjectUUID() == 13171) {
|
||||
checkForRespawn(mob);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
|
||||
// Filter hirelings by slot type
|
||||
|
||||
for (Item hirelings : player.getInventory()) {
|
||||
if (hirelings.template.item_type.equals(ItemType.EMPLOYMENTCONTRACT)) {
|
||||
if (hirelings.template.getItemType().equals(ItemType.EMPLOYMENTCONTRACT)) {
|
||||
|
||||
contract = DbManager.ContractQueries.GET_CONTRACT(hirelings.templateID);
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler {
|
||||
if (!item.validForInventory(source.getClientConnection(), source, source.charItemManager))
|
||||
return false;
|
||||
|
||||
if (!tradingWith.hasRoomTrade(item.template.item_wt)) {
|
||||
if (!tradingWith.hasRoomTrade(item.template.getItemWt())) {
|
||||
dispatch = Dispatch.borrow(source, msg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
return false;
|
||||
|
||||
@@ -97,9 +97,13 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
|
||||
if (city == null)
|
||||
return true;
|
||||
|
||||
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
|
||||
Warehouse.destroyedWarehouses.remove(building.getObjectUUID());
|
||||
|
||||
city.warehouse = null;
|
||||
// Rubble no longer owns city.warehouse, which may be null or a newly placed warehouse
|
||||
if (city.warehouse != null && building.getRank() != -1) {
|
||||
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
|
||||
city.warehouse = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import engine.net.client.msg.guild.GuildInfoMsg;
|
||||
import engine.objects.Guild;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.parsers.objects.DeedTemplate;
|
||||
import engine.util.StringUtils;
|
||||
|
||||
public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
||||
@@ -42,6 +43,7 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
||||
Guild playerGuild;
|
||||
|
||||
Item charter;
|
||||
DeedTemplate charterDeed;
|
||||
Dispatch dispatch;
|
||||
|
||||
msg = (GuildCreationFinalizeMsg) baseMsg;
|
||||
@@ -65,7 +67,9 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// Item must be a valid charterType (type 10 in db)
|
||||
|
||||
if (charter == null || (charter.template.item_type.equals(ItemType.CHARTER) == false)) {
|
||||
charterDeed = DeedTemplate._deeds.get(charter.templateID);
|
||||
|
||||
if (charterDeed == null || (charterDeed.item_type.equals(ItemType.CHARTER) == false)) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, GuildManager.NO_CHARTER_FOUND);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,12 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (vendor == null)
|
||||
return true;
|
||||
|
||||
// Same access rule as opening the vendor's management window (OrderNPCMsgHandler); never trust the client
|
||||
|
||||
if (!BuildingManager.PlayerCanControlNotOwner(vendor.getBuilding(), player)
|
||||
&& !BuildingManager.playerCanManage(player, vendor.getBuilding()))
|
||||
return true;
|
||||
|
||||
// Process Request
|
||||
|
||||
switch (msg.actionType) {
|
||||
@@ -238,10 +244,10 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (targetItem == null)
|
||||
return;
|
||||
|
||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
||||
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||
return;
|
||||
|
||||
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.item_wt)) {
|
||||
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.getItemWt())) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, 21);
|
||||
return;
|
||||
}
|
||||
@@ -299,6 +305,11 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (vendor.getBuilding() == null)
|
||||
return;
|
||||
|
||||
// NPC buildings have no strongbox to refund into
|
||||
|
||||
if (vendor.getBuilding().getProtectionState() == mbEnums.ProtectionState.NPC)
|
||||
return;
|
||||
|
||||
PlayerCharacter player = origin.getPlayerCharacter();
|
||||
|
||||
if (player == null)
|
||||
@@ -319,7 +330,7 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (targetItem == null)
|
||||
continue;
|
||||
|
||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
||||
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||
return;
|
||||
|
||||
if (!vendor.charItemManager.doesCharOwnThisItem(targetItem.getObjectUUID()))
|
||||
@@ -328,14 +339,14 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (!vendor.charItemManager.inventoryContains(targetItem))
|
||||
continue;
|
||||
|
||||
itemValue = targetItem.template.item_value;
|
||||
itemValue = targetItem.template.getItemValue();
|
||||
|
||||
if (vendor.getBuilding().getStrongboxValue() + itemValue > vendor.getBuilding().getMaxGold()) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, 201);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (targetItem.template.item_type) {
|
||||
switch (targetItem.template.getItemType()) {
|
||||
case EMPLOYMENTCONTRACT:
|
||||
case CHARTER:
|
||||
case DEED:
|
||||
@@ -465,13 +476,13 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (targetItem == null)
|
||||
return;
|
||||
|
||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
||||
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||
return;
|
||||
|
||||
if (!vendor.charItemManager.inventoryContains(targetItem))
|
||||
return;
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(targetItem.template.item_wt))
|
||||
if (!player.charItemManager.hasRoomInventory(targetItem.template.getItemWt()))
|
||||
return;
|
||||
|
||||
player.charItemManager.buyFromNPC(targetItem, vendor);
|
||||
|
||||
@@ -161,7 +161,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
||||
if (itemRet == null)
|
||||
return true;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
// this is done to prevent the temporary goldItem item
|
||||
// (from the mob) from appearing in player's inventory.
|
||||
// It also updates the goldItem quantity display
|
||||
@@ -187,7 +187,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
||||
//TODO send group loot message if player is grouped and visible
|
||||
Group group = GroupManager.getGroup(player);
|
||||
|
||||
if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
if (group != null && group.getSplitGold() && (item.template.getItemType().equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
String name = item.getName();
|
||||
String text = player.getFirstName() + " has looted " + name + '.';
|
||||
ChatManager.chatGroupInfoCanSee(player, text);
|
||||
@@ -202,7 +202,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
||||
if (itemRet == null)
|
||||
return true;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
// this is done to prevent the temporary goldItem item
|
||||
// (from the mob) from appearing in player's inventory.
|
||||
// It also updates the goldItem quantity display
|
||||
@@ -241,7 +241,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
||||
//TODO send group loot message if player is grouped and visible
|
||||
Group group = GroupManager.getGroup(player);
|
||||
|
||||
if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
if (group != null && group.getSplitGold() && (item.template.getItemType().equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
String name = item.getName();
|
||||
String text = player.getFirstName() + " has looted " + name + '.';
|
||||
ChatManager.chatGroupInfoCanSee(player, text);
|
||||
|
||||
@@ -141,17 +141,9 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
City city = building.getCity();
|
||||
Warehouse warehouse = Warehouse.destroyedWarehouses.get(building.getObjectUUID());
|
||||
|
||||
if (city == null)
|
||||
return true;
|
||||
|
||||
Warehouse warehouse = city.warehouse;
|
||||
|
||||
if (warehouse == null)
|
||||
return true;
|
||||
|
||||
if (Warehouse.isEmpty(warehouse)) {
|
||||
if (warehouse == null || Warehouse.isEmpty(warehouse)) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.DeedTemplate;
|
||||
import engine.powers.PowersBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -78,7 +79,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
int uuid = item.templateID;
|
||||
|
||||
switch (item.template.item_type) {
|
||||
switch (item.template.getItemType()) {
|
||||
|
||||
case DEED: //buildings
|
||||
//Call add building screen here, ib.getUseID() get's building ID
|
||||
@@ -99,7 +100,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
pam.setX(loc.getX() + 64); //offset grid from tol
|
||||
pam.setY(loc.getY());
|
||||
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
||||
pam.addPlacementInfo(item.template.deed_structure_id);
|
||||
pam.addPlacementInfo(DeedTemplate._deeds.get(item.templateID).deed_structure_id);
|
||||
|
||||
dispatch = Dispatch.borrow(player, pam);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
|
||||
@@ -187,14 +188,14 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (uuid > 680069 && uuid < 680074) //Handle Charter, Deed, Petition, Warrant here
|
||||
break;
|
||||
|
||||
if (item.template.item_bane_rank > 0) {
|
||||
if (item.template.getItemBaneRank() > 0) {
|
||||
|
||||
// Only one banestone at a time
|
||||
|
||||
lock.writeLock().lock();
|
||||
|
||||
try {
|
||||
if (Bane.summonBanestone(player, origin, item.template.item_bane_rank) == true)
|
||||
if (Bane.summonBanestone(player, origin, item.template.getItemBaneRank()) == true)
|
||||
itemMan.consume(item);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
@@ -225,7 +226,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// Bypass for waterbuckets
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.BUCKET)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.BUCKET)) {
|
||||
|
||||
// test for valid target type
|
||||
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
|
||||
@@ -250,10 +251,9 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
}
|
||||
|
||||
if (waterbucketBypass == false) {
|
||||
String powerString = item.template.item_power_grant.keySet().iterator().next();
|
||||
PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerString);
|
||||
int powerValue = item.template.item_power_grant.get(powerString);
|
||||
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerValue, true);
|
||||
engine.parsers.objects.PowerGrant powerGrant = item.template.getItemPowerGrant().get(0);
|
||||
PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerGrant.power_type);
|
||||
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerGrant.power_value, true);
|
||||
}
|
||||
itemMan.consume(item);
|
||||
} else //just remove the item at this point
|
||||
@@ -266,7 +266,8 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
case RUNE:
|
||||
if(ApplyRuneMsg.applyRune(uuid, origin, player)) {
|
||||
itemMan.consume(item);
|
||||
}
|
||||
} else
|
||||
ErrorPopupMsg.sendErrorPopup(player, 161);
|
||||
break;
|
||||
default: //shouldn't be here, consume item
|
||||
dispatch = Dispatch.borrow(player, msg);
|
||||
|
||||
@@ -18,6 +18,7 @@ import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg.PlacementInfo;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.DeedTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -135,6 +136,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) {
|
||||
|
||||
Bane bane;
|
||||
|
||||
if (serverZone.guild_zone == false) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
|
||||
return false;
|
||||
@@ -205,6 +208,15 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Siege equipment has its own validation and never reaches here
|
||||
|
||||
bane = city.getBane();
|
||||
|
||||
if (bane != null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 74, ""); //"Only buildings of war may be placed during a bane"
|
||||
return false;
|
||||
}
|
||||
|
||||
if (placementCollisionCheck(serverZone, origin, placementInfo)) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 3, ""); // Conflict between proposed assets
|
||||
return false;
|
||||
@@ -345,8 +357,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
Item contract = null;
|
||||
|
||||
for (Item inventoryItem : playerCharacter.getInventory()) {
|
||||
if (inventoryItem.template.item_type.equals(ItemType.DEED) &&
|
||||
inventoryItem.template.deed_structure_id == buildingList.getBlueprintUUID()) {
|
||||
if (inventoryItem.template.getItemType().equals(ItemType.DEED) &&
|
||||
DeedTemplate._deeds.get(inventoryItem.templateID).deed_structure_id == buildingList.getBlueprintUUID()) {
|
||||
contract = inventoryItem;
|
||||
break;
|
||||
}
|
||||
@@ -1168,10 +1180,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// if W return is negative, this is a -90 rotation not a 90?
|
||||
|
||||
newMesh = DbManager.BuildingQueries.CREATE_BUILDING(
|
||||
currentZone.getObjectUUID(), playerCharacter.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
|
||||
newMesh = Building.persistBuilding(Building.createBuilding(
|
||||
currentZone, playerCharacter.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
|
||||
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0,
|
||||
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
|
||||
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation));
|
||||
|
||||
// Make sure we have a valid mesh
|
||||
|
||||
@@ -1291,10 +1303,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
DateTime completionDate = DateTime.now().plusHours(blueprint.getRankTime(1));
|
||||
|
||||
|
||||
newMesh = DbManager.BuildingQueries.CREATE_BUILDING(
|
||||
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
|
||||
newMesh = Building.persistBuilding(Building.createBuilding(
|
||||
currentZone, player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
|
||||
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0,
|
||||
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
|
||||
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation));
|
||||
|
||||
// Make sure we have a valid mesh
|
||||
if (newMesh == null) {
|
||||
@@ -1330,10 +1342,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
City city = City.getCity(currentZone.playerCityUUID);
|
||||
|
||||
warehouseBuilding = DbManager.BuildingQueries.CREATE_BUILDING(
|
||||
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
|
||||
warehouseBuilding = Building.persistBuilding(Building.createBuilding(
|
||||
currentZone, player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
|
||||
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0,
|
||||
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
|
||||
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation));
|
||||
|
||||
if (warehouseBuilding == null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
|
||||
@@ -1341,6 +1353,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
}
|
||||
|
||||
Warehouse warehouse = new Warehouse(warehouseBuilding);
|
||||
Warehouse.destroyedWarehouses.values().removeIf(destroyed -> destroyed.city == city);
|
||||
city.warehouse = warehouse;
|
||||
DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse);
|
||||
|
||||
@@ -1350,7 +1363,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
MaintenanceManager.setMaintDateTime(warehouseBuilding, LocalDateTime.now().plusDays(7));
|
||||
warehouseBuilding.setLoc(warehouseBuilding.getLoc());
|
||||
InterestManager.setObjectDirty(warehouseBuilding);
|
||||
warehouseBuilding.runAfterLoad();
|
||||
|
||||
if (city == null)
|
||||
return true;
|
||||
|
||||
@@ -13,6 +13,7 @@ import engine.mbEnums;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ClientNetMsg;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.RefineMsg;
|
||||
import engine.net.client.msg.RefinerScreenMsg;
|
||||
import engine.objects.*;
|
||||
@@ -88,6 +89,9 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
|
||||
public static boolean refineSkill(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) {
|
||||
CharacterSkill skill = null;
|
||||
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
|
||||
int refinedAmount;
|
||||
int requiredAmount;
|
||||
|
||||
for (CharacterSkill sk : skills.values()) {
|
||||
if (sk == null)
|
||||
continue;
|
||||
@@ -106,17 +110,16 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
//TODO verify if any skills have this as prereq
|
||||
|
||||
//TODO verify if any powers have this as a prereq
|
||||
//get all players powers
|
||||
// Dropping below a trained power's skill requirement would make calculatePowers delete the power and its trains
|
||||
refinedAmount = Math.round(skill.getBaseAmountBeforeMods() + skill.calculateAmountAfterTrains(skill.getNumTrains() - 1));
|
||||
|
||||
for (CharacterPower power : pc.getPowers().values()) {
|
||||
ArrayList<PowerReq> reqs = PowerReq.getPowerReqsForRune(power.getPowerID());
|
||||
for (PowerReq req : reqs) {
|
||||
ConcurrentHashMap<String, CharacterSkill> playerSkills = pc.getSkills();
|
||||
CharacterSkill playerSkill = playerSkills.get(token);
|
||||
int currentSkillLevel = playerSkill.getTotalSkillPercet();
|
||||
if (token == req.getToken() && req.getLevel() == currentSkillLevel) {
|
||||
return false;
|
||||
}
|
||||
if (power.getTrains() < 1)
|
||||
continue;
|
||||
requiredAmount = getRequiredSkillAmount(pc, power.getPower().getToken(), token);
|
||||
if (refinedAmount < requiredAmount) {
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You must refine " + power.getPower().getName() + " to 0 before refining any more from this skill.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +127,36 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
|
||||
return skill.refine(pc);
|
||||
}
|
||||
|
||||
private static int getRequiredSkillAmount(PlayerCharacter pc, int powerToken, int skillToken) {
|
||||
int requiredAmount = 0;
|
||||
|
||||
if (pc.race != null)
|
||||
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.race.getPowersGranted(), powerToken, skillToken));
|
||||
if (pc.baseClass != null)
|
||||
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.baseClass.getPowersGranted(), powerToken, skillToken));
|
||||
if (pc.promotionClass != null)
|
||||
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.promotionClass.getPowersGranted(), powerToken, skillToken));
|
||||
if (pc.getRunes() != null)
|
||||
for (CharacterRune rune : pc.getRunes())
|
||||
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(rune.getPowersGranted(), powerToken, skillToken));
|
||||
|
||||
return requiredAmount;
|
||||
}
|
||||
|
||||
private static int getRequiredSkillAmount(ArrayList<PowerReq> powersGranted, int powerToken, int skillToken) {
|
||||
Byte requiredAmount;
|
||||
|
||||
for (PowerReq powerReq : powersGranted) {
|
||||
if (powerReq.getToken() != powerToken)
|
||||
continue;
|
||||
requiredAmount = powerReq.getSkillReqs().get(skillToken);
|
||||
if (requiredAmount != null)
|
||||
return requiredAmount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static boolean refinePower(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) {
|
||||
CharacterPower power = null;
|
||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||
|
||||
@@ -85,7 +85,7 @@ public class RepairMsgHandler extends AbstractClientMsgHandler {
|
||||
//make sure item is damaged and not destroyed
|
||||
|
||||
short dur = (short) toRepair.combat_health_current;
|
||||
short max = (short) toRepair.template.combat_health_full;
|
||||
short max = (short) toRepair.template.getCombatHealthFull();
|
||||
|
||||
//account for durability modifications
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
|
||||
if (!itemManager.moveGoldToInventory(item, msg.getNumItems()))
|
||||
return true;
|
||||
@@ -85,7 +85,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// Not gold, process update here
|
||||
|
||||
if (!itemManager.hasRoomInventory(item.template.item_wt))
|
||||
if (!itemManager.hasRoomInventory(item.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
if (itemManager.moveItemToInventory(item) == false)
|
||||
|
||||
@@ -65,7 +65,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
|
||||
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && itemManager.isBankOpen())
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
if (!itemManager.moveGoldToBank(item, msg.getNumItems()))
|
||||
return true;
|
||||
UpdateGoldMsg goldMes = new UpdateGoldMsg(player);
|
||||
@@ -76,7 +76,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
} else {
|
||||
|
||||
if (!itemManager.hasRoomBank(item.template.item_wt))
|
||||
if (!itemManager.hasRoomBank(item.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
if (!itemManager.moveItemToBank(item))
|
||||
|
||||
@@ -86,7 +86,7 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
|
||||
if (me.objectUUID == vendorBuyMsg.getItemID()) {
|
||||
|
||||
//test room available for item
|
||||
if (!itemMan.hasRoomInventory(me.template.item_wt))
|
||||
if (!itemMan.hasRoomInventory(me.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
int cost = me.getValue();
|
||||
@@ -148,10 +148,10 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
//test room available for item
|
||||
|
||||
if (!itemMan.hasRoomInventory(vendorItem.template.item_wt))
|
||||
if (!itemMan.hasRoomInventory(vendorItem.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
int cost = vendorItem.template.item_value;
|
||||
int cost = vendorItem.template.getItemValue();
|
||||
|
||||
if (vendorItem.flags.contains(mbEnums.ItemFlags.Identified) || vendorItem.isCustomValue())
|
||||
cost = vendorItem.magicValue;
|
||||
|
||||
Loaded 100 of 322 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user