Public Repository for the Magicbane Shadowbane Emulator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
13 KiB

package engine.net.client.handlers;
import engine.Enum;
import engine.Enum.DispatchChannel;
import engine.Enum.GameObjectType;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.SessionManager;
import engine.gameManager.ZoneManager;
import engine.math.Bounds;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.ManageCityAssetsMsg;
import engine.net.client.msg.PlaceAssetMsg;
import engine.objects.*;
import org.joda.time.DateTime;
/*
* @Author:
* @Summary: Processes application protocol message which opens
* and processes the various building asset management windows.
*/
public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
public ManageCityAssetMsgHandler() {
super(ManageCityAssetsMsg.class);
}
public static boolean playerCanManageNotFriends(PlayerCharacter player, Building building) {
//Player Can only Control Building if player is in Same Guild as Building and is higher rank than IC.
if (player == null)
return false;
if (building.getRank() == -1)
return false;
if (BuildingManager.IsOwner(building, player))
return true;
if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false)
return false;
//Somehow guild leader check fails above? lets check if Player is true Guild GL.
if (building.getGuild() != null && building.getGuild().isGuildLeader(player.getObjectUUID()))
return true;
return Guild.sameGuild(building.getGuild(), player.getGuild());
}
@Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {
ManageCityAssetsMsg msg;
PlayerCharacter player;
ManageCityAssetsMsg outMsg;
Building building;
msg = (ManageCityAssetsMsg) baseMsg;
player = SessionManager.getPlayerCharacter(origin);
if (player == null)
return true;
building = BuildingManager.getBuildingFromCache(msg.getTargetID());
if (building == null) {
if (msg.actionType == 14) {
Zone zone = ZoneManager.findSmallestZone(player.getLoc());
if (!zone.isPlayerCity()) {
ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command.");
return true;
}
City city = City.GetCityFromCache(zone.getPlayerCityUUID());
if (city == null || !city.getGuild().equals(player.getGuild()) ||
(!GuildStatusController.isInnerCouncil(player.getGuildStatus()) &&
!GuildStatusController.isGuildLeader(player.getGuildStatus()))) {
ErrorPopupMsg.sendErrorMsg(player, "You are not in the correct guild to command this city.");
return true;
}
ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building);
mca.actionType = 15;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, mca), DispatchChannel.SECONDARY);
}
return true;
}
outMsg = new ManageCityAssetsMsg(player, building);
if (player.isSafeMode()) {
outMsg.actionType = 4;
outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID());
outMsg.setAssetName(building.getName());
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true;
}
switch (msg.actionType) {
case 2:
case 22:
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() == engine.Enum.BuildingGroup.BANESTONE) {
outMsg.actionType = 18;
outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID());
} else if (BuildingManager.playerCanManage(player, building)) {
configWindowState(player, building, outMsg);
outMsg.actionType = 3;
outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID());
outMsg.setTargetType3(building.getObjectType().ordinal());
outMsg.setTargetID3(building.getObjectUUID());
outMsg.setUnknown54(1);
} else {
// Handle other cases
if (building.getRank() == -1) {
if (!Bounds.collide(player.getLoc(), building)) {
ErrorPopupMsg.sendErrorPopup(player, 64);
return true;
}
switch (building.getBlueprint().getBuildingGroup()) {
case SHRINE:
Shrine shrine = Shrine.shrinesByBuildingUUID.get(building.getObjectUUID());
if (shrine == null || shrine.getFavors() == 0) {
ErrorPopupMsg.sendErrorPopup(player, 166); // There is no more favor in this shrine to loot
return true;
}
//loot elan stones
MobLoot elanStones = new MobLoot(player,ItemBase.getItemBase(1705032),1,false);
Item promotedItem = elanStones.promoteToItem(player);
promotedItem.setNumOfItems(shrine.getFavors());
player.getCharItemManager().addItemToInventory(promotedItem);
DbManager.ItemQueries.UPDATE_NUM_ITEMS(promotedItem,promotedItem.getNumOfItems(),1);
player.getCharItemManager().updateInventory();
shrine.setFavors(0);
break;
case WAREHOUSE:
Warehouse warehouse = Warehouse.warehouseByBuildingUUID.get(building.getObjectUUID());
if (warehouse == null || warehouse.isEmpty()) {
ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources.
return true;
}
break;
}
}
AbstractCharacter owner = building.getOwner();
if (owner == null) {
msg.actionType = 4;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, msg), DispatchChannel.SECONDARY);
} else {
outMsg.actionType = 4;
outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID());
outMsg.setAssetName(building.getName());
}
}
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true;
case 13:
outMsg.actionType = 13;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true;
case 5:
building.setName(msg.getAssetName());
configWindowState(player, building, outMsg);
outMsg.actionType = 3;
outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID());
outMsg.setTargetType3(GameObjectType.Building.ordinal());
outMsg.setTargetID3(building.getObjectUUID());
outMsg.setAssetName1(building.getName());
outMsg.setUnknown54(1);
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true;
case 14:
ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building);
mca.actionType = 15;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, mca), DispatchChannel.SECONDARY);
return true;
case 20:
// Handle case 20
return handleCase20(player, outMsg, building, msg, origin);
default:
return true;
}
}
private boolean handleCase20(PlayerCharacter player, ManageCityAssetsMsg outMsg, Building building, ManageCityAssetsMsg msg, ClientConnection origin) throws MsgSendException {
Zone baneZone = building.getParentZone();
if (baneZone == null)
return true;
City banedCity = City.getCity(baneZone.getPlayerCityUUID());
if (banedCity == null)
return true;
Bane bane = banedCity.getBane();
if (bane == null || bane.getLiveDate() != null || player.getGuild() != banedCity.getGuild() || !GuildStatusController.isInnerCouncil(player.getGuildStatus()))
return true;
int baneHour = msg.getBaneHour();
if (baneHour < 16 || baneHour > 24) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return true;
}
DateTime baneLive = new DateTime(bane.getPlacementDate());
baneLive = baneHour == 24 ? baneLive.plusDays(3) : baneLive.plusDays(2);
baneLive = baneHour == 24 ? baneLive.hourOfDay().setCopy(0) : baneLive.hourOfDay().setCopy(baneHour);
baneLive = baneLive.minuteOfHour().setCopy(0);
baneLive = baneLive.secondOfMinute().setCopy(1);
bane.setLiveDate(baneLive);
outMsg.actionType = 18;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true;
}
public void configWindowState(PlayerCharacter player, Building building, ManageCityAssetsMsg manageCityAssetsMsg) {
// Tests to turn on upgrade button if a building is not
// at it's maximum allowed rank or currently ranking
// Owner is obviously allowed to upgrade his own buildings
if (building.getOwner() != null && building.getOwner().equals(player)) {
// Players cannot destroy or transfer a TOL.
if (building.getBlueprint() == null) {
manageCityAssetsMsg.buttonDestroy = 0;
manageCityAssetsMsg.buttonTransfer = 0;
manageCityAssetsMsg.buttonAbandon = 0;
manageCityAssetsMsg.buttonUpgrade = 0;
} else if (building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.TOL) {
manageCityAssetsMsg.buttonDestroy = 0;
manageCityAssetsMsg.buttonTransfer = 0;
manageCityAssetsMsg.buttonAbandon = 1;
manageCityAssetsMsg.buttonUpgrade = 1;
} else if (building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.MINE) {
manageCityAssetsMsg.buttonDestroy = 0;
manageCityAssetsMsg.buttonTransfer = 0;
manageCityAssetsMsg.buttonAbandon = 0;
manageCityAssetsMsg.buttonUpgrade = 0; // Cannot upgrade a mine
} else {
manageCityAssetsMsg.buttonDestroy = 1;
manageCityAssetsMsg.buttonTransfer = 1;
manageCityAssetsMsg.buttonAbandon = 1;
manageCityAssetsMsg.buttonUpgrade = 1;
}
}
// Inner Council of the same guild can also upgrade
if ((player.getGuild().equals(building.getGuild())) &&
GuildStatusController.isInnerCouncil(player.getGuildStatus()))
manageCityAssetsMsg.buttonUpgrade = 1;
// Disable upgrade button if at max rank.
if (building.getBlueprint() == null)
manageCityAssetsMsg.buttonUpgrade = 0;
else if (building.getRank() >= building.getBlueprint().getMaxRank())
manageCityAssetsMsg.buttonUpgrade = 0;
;
// If a building is not protected we can exit here
if (building.assetIsProtected() == false)
return;
// Protection is displayed as "UNDER SIEGE" if
// an active bane is invalidating the protection
// contracts of the city.
if ((building.getCity() != null) &&
(building.getCity().protectionEnforced == false)) {
manageCityAssetsMsg.labelProtected = 0;
manageCityAssetsMsg.labelSiege = 1;
manageCityAssetsMsg.labelCeaseFire = 0;
return;
}
// Building is currently protected by a TOL
manageCityAssetsMsg.labelProtected = 1;
}
}