|
|
|
package engine.net.client.handlers;
|
|
|
|
|
|
|
|
import engine.exception.MsgSendException;
|
|
|
|
import engine.gameManager.*;
|
|
|
|
import engine.math.Bounds;
|
|
|
|
import engine.math.Vector3fImmutable;
|
|
|
|
import engine.mbEnums;
|
|
|
|
import engine.net.Dispatch;
|
|
|
|
import engine.net.client.ClientConnection;
|
|
|
|
import engine.net.client.msg.*;
|
|
|
|
import engine.objects.*;
|
|
|
|
import engine.powers.PowersBase;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @Author:
|
|
|
|
* @Summary: Processes application protocol message which handles
|
|
|
|
* items in the character's inventory which are used. Potions, Deeds, etc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|
|
|
|
|
|
|
// Reentrant lock for dropping banes
|
|
|
|
|
|
|
|
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
|
|
|
|
|
|
|
public ObjectActionMsgHandler() {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {
|
|
|
|
|
|
|
|
// Member variable declaration
|
|
|
|
ObjectActionMsg msg;
|
|
|
|
PlayerCharacter player;
|
|
|
|
CharacterItemManager itemMan;
|
|
|
|
ArrayList<Long> comps;
|
|
|
|
Dispatch dispatch;
|
|
|
|
boolean waterbucketBypass = false;
|
|
|
|
|
|
|
|
// Member variable assignment
|
|
|
|
msg = (ObjectActionMsg) baseMsg;
|
|
|
|
player = SessionManager.getPlayerCharacter(origin);
|
|
|
|
|
|
|
|
if (player == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
itemMan = player.charItemManager;
|
|
|
|
|
|
|
|
if (itemMan == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
comps = msg.getTargetCompID();
|
|
|
|
|
|
|
|
if (comps.isEmpty()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
long comp = comps.get(0);
|
|
|
|
|
|
|
|
if (((int) comp) != 0) {
|
|
|
|
Item item = Item.getFromCache((int) comp);
|
|
|
|
|
|
|
|
if (item == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//dupe check
|
|
|
|
if (!item.validForInventory(origin, player, itemMan)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemMan.doesCharOwnThisItem(item.getObjectUUID())) {
|
|
|
|
|
|
|
|
int uuid = item.templateID;
|
|
|
|
|
|
|
|
switch (item.template.item_type) {
|
|
|
|
|
|
|
|
case DEED: //buildings
|
|
|
|
//Call add building screen here, ib.getUseID() get's building ID
|
|
|
|
|
|
|
|
//if inside player city, center loc on tol. otherwise center on player.
|
|
|
|
Vector3fImmutable loc = player.getLoc();
|
|
|
|
Zone zone = ZoneManager.findSmallestZone(player.getLoc());
|
|
|
|
|
|
|
|
if (zone != null) {
|
|
|
|
if (zone.guild_zone) {
|
|
|
|
loc = zone.getLoc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PlaceAssetMsg pam = new PlaceAssetMsg();
|
|
|
|
pam.setActionType(2);
|
|
|
|
pam.setContractID(item.getObjectUUID());
|
|
|
|
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);
|
|
|
|
|
|
|
|
dispatch = Dispatch.borrow(player, pam);
|
|
|
|
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
|
|
|
|
|
|
|
|
//itemMan.consume(item); //temporary fix for dupe.. TODO Make Item Unusable after This message is sent.
|
|
|
|
break;
|
|
|
|
case FURNITUREDEED: //furniture
|
|
|
|
//Call add furniture screen here. ib.getUseID() get's furniture ID
|
|
|
|
break;
|
|
|
|
case OFFERING:
|
|
|
|
long shrineCompID = comps.get(1);
|
|
|
|
Building shrineBuilding = BuildingManager.getBuilding((int) shrineCompID);
|
|
|
|
if (shrineBuilding == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (shrineBuilding.getBlueprint() != null && shrineBuilding.getBlueprint().getBuildingGroup() != mbEnums.BuildingGroup.SHRINE) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shrineBuilding.getRank() == -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
Shrine shrine = Shrine.shrinesByBuildingUUID.get(shrineBuilding.getObjectUUID());
|
|
|
|
|
|
|
|
if (shrine == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shrine.addFavor(player, item)) {
|
|
|
|
shrineBuilding.addEffectBit(1000000 << 2);
|
|
|
|
shrineBuilding.updateEffects();
|
|
|
|
shrineBuilding.removeEffectBit(1000000 << 2);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REALMCHARTER:
|
|
|
|
int charterType = 0;
|
|
|
|
switch (uuid) {
|
|
|
|
case 910020:
|
|
|
|
charterType = 762228431;
|
|
|
|
break;
|
|
|
|
case 910021:
|
|
|
|
charterType = -15978914;
|
|
|
|
break;
|
|
|
|
case 910022:
|
|
|
|
charterType = -600065291;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (Realm.claimRealm(player, charterType) == true) {
|
|
|
|
itemMan.consume(item);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WAND: //rod of command
|
|
|
|
long compID = comps.get(1);
|
|
|
|
|
|
|
|
int objectType = AbstractWorldObject.extractTypeID(compID).ordinal();
|
|
|
|
Mob toCommand;
|
|
|
|
if (objectType == mbEnums.GameObjectType.Mob.ordinal()) {
|
|
|
|
toCommand = Mob.getFromCache((int) compID);
|
|
|
|
} //Only Command Mob Types.
|
|
|
|
else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (toCommand == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!toCommand.isSiege())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (player.commandSiegeMinion(toCommand)) {
|
|
|
|
itemMan.consume(item);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
//ANNIVERSERY GIFT
|
|
|
|
case TREASURE:
|
|
|
|
// *** Disabled for now: Needs bootyset created
|
|
|
|
LootManager.peddleFate(player, item);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BUCKET: //water bucket
|
|
|
|
case POTION: //potions, tears of saedron
|
|
|
|
case SCROLL: //runes, petition, warrant, scrolls
|
|
|
|
if (uuid > 680069 && uuid < 680074) //Handle Charter, Deed, Petition, Warrant here
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (item.template.item_bane_rank > 0) {
|
|
|
|
|
|
|
|
// Only one banestone at a time
|
|
|
|
|
|
|
|
lock.writeLock().lock();
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (Bane.summonBanestone(player, origin, item.template.item_bane_rank) == true)
|
|
|
|
itemMan.consume(item);
|
|
|
|
} finally {
|
|
|
|
lock.writeLock().unlock();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uuid == 910010) { //tears of saedron
|
|
|
|
if (comps.size() > 1)
|
|
|
|
AbstractCharacter.removeRune(player, origin, comps.get(1).intValue());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item.chargesRemaining > 0) {
|
|
|
|
ArrayList<Long> tarList = msg.getTargetCompID();
|
|
|
|
AbstractWorldObject target = player;
|
|
|
|
|
|
|
|
if (tarList.size() > 1) {
|
|
|
|
long tarID = tarList.get(1);
|
|
|
|
|
|
|
|
if (tarID != 0) {
|
|
|
|
AbstractGameObject tarAgo = AbstractGameObject.getFromTypeAndID(tarID);
|
|
|
|
if (tarAgo instanceof AbstractWorldObject) {
|
|
|
|
target = (AbstractWorldObject) tarAgo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bypass for waterbuckets
|
|
|
|
|
|
|
|
if (item.template.item_type.equals(mbEnums.ItemType.BUCKET)) {
|
|
|
|
|
|
|
|
// test for valid target type
|
|
|
|
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
|
|
|
|
waterbucketBypass = true;
|
|
|
|
else {
|
|
|
|
// test distance to structure
|
|
|
|
Building targetBuilding = (Building) target;
|
|
|
|
Bounds testBounds = Bounds.borrow();
|
|
|
|
testBounds.setBounds(player.getLoc(), 25);
|
|
|
|
|
|
|
|
if (Bounds.collide(targetBuilding.getBounds(), testBounds, .1f) == false) {
|
|
|
|
ChatManager.chatSystemError(player, "Not in range of structura for to heal!");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send piss bucket animation
|
|
|
|
|
|
|
|
VisualUpdateMessage vum = new VisualUpdateMessage(player, 16323);
|
|
|
|
vum.configure();
|
|
|
|
DispatchManager.sendToAllInRange(player, vum);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
itemMan.consume(item);
|
|
|
|
} else //just remove the item at this point
|
|
|
|
itemMan.consume(item);
|
|
|
|
|
|
|
|
dispatch = Dispatch.borrow(player, msg);
|
|
|
|
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
|
|
|
|
player.cancelOnSpell();
|
|
|
|
break;
|
|
|
|
case RUNE:
|
|
|
|
ApplyRuneMsg.applyRune(uuid,origin,player);
|
|
|
|
itemMan.consume(item);
|
|
|
|
break;
|
|
|
|
default: //shouldn't be here, consume item
|
|
|
|
dispatch = Dispatch.borrow(player, msg);
|
|
|
|
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
|
|
|
|
// itemMan.consume(item);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// TODO log item does not belong to player
|
|
|
|
// System.out.println("Item does not belong to player");
|
|
|
|
// Cleanup duped item here
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|