From dba74a6ebcad7be614209ea4f91fd3e294c44554 Mon Sep 17 00:00:00 2001 From: Treeku Date: Sat, 3 May 2014 15:32:07 +0100 Subject: [PATCH] Fixed calculatePvpStatus --- scripts/commands/pvp.py | 12 +- src/resources/datatables/PvpStatus.java | 2 +- .../objects/creature/CreatureObject.java | 6 +- .../objects/tangible/TangibleObject.java | 5 + src/services/gcw/FactionService.java | 185 ++++++++++++------ 5 files changed, 146 insertions(+), 64 deletions(-) diff --git a/scripts/commands/pvp.py b/scripts/commands/pvp.py index 1260a24c..c313fbc4 100644 --- a/scripts/commands/pvp.py +++ b/scripts/commands/pvp.py @@ -48,30 +48,30 @@ def run(core, actor, target, commandString): if factionStatus == FactionStatus.OnLeave: actor.sendSystemMessage('@faction_recruiter:on_leave_to_covert', 0) - #actor.setPvpStatus(PvpStatus.GoingCovert, True) + actor.setPvpStatus(PvpStatus.GoingCovert, True) time.sleep(1) actor.setFactionStatus(FactionStatus.Combatant) - #actor.setPvpStatus(PvpStatus.GoingCovert, False) + actor.setPvpStatus(PvpStatus.GoingCovert, False) actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) actor.updatePvpStatus() return if factionStatus == FactionStatus.Combatant: actor.sendSystemMessage('@faction_recruiter:covert_to_overt', 0) - #actor.setPvpStatus(PvpStatus.GoingOvert, True) + actor.setPvpStatus(PvpStatus.GoingOvert, True) time.sleep(30) actor.setFactionStatus(FactionStatus.SpecialForces) - #actor.setPvpStatus(PvpStatus.GoingOvert, False) + actor.setPvpStatus(PvpStatus.GoingOvert, False) actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) actor.updatePvpStatus() return if factionStatus == FactionStatus.SpecialForces: actor.sendSystemMessage('@faction_recruiter:overt_to_covert', 0) - #actor.setPvpStatus(PvpStatus.GoingCovert, True) + actor.setPvpStatus(PvpStatus.GoingCovert, True) time.sleep(300) actor.setFactionStatus(FactionStatus.Combatant) - #actor.setPvpStatus(PvpStatus.GoingCovert, False) + actor.setPvpStatus(PvpStatus.GoingCovert, False) actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) actor.updatePvpStatus() return diff --git a/src/resources/datatables/PvpStatus.java b/src/resources/datatables/PvpStatus.java index ddded7a4..f2bb3350 100644 --- a/src/resources/datatables/PvpStatus.java +++ b/src/resources/datatables/PvpStatus.java @@ -32,6 +32,6 @@ public class PvpStatus { public static int Enemy = 32; public static int GoingOvert = 64; public static int GoingCovert = 128; - public static int Dueling = 256; + public static int Self = 256; } diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 10795671..67311a79 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -559,12 +559,14 @@ public class CreatureObject extends TangibleObject implements Serializable { synchronized(objectMutex) { if (state != 0) { if (add) { - stateBitmask = (stateBitmask | state); + state = (stateBitmask | state); } else { - stateBitmask = (stateBitmask & ~state); + state = (stateBitmask & ~state); } } } + + notifyObservers(messageBuilder.buildStateDelta(state), true); } public boolean getState(long state) { diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index fb8fc9ef..cb2e4f3f 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -41,6 +41,7 @@ import protocol.swg.objectControllerObjects.ShowFlyText; import resources.common.OutOfBand; import resources.common.RGB; import resources.datatables.Options; +import resources.datatables.PvpStatus; import resources.loot.LootGroup; import resources.objects.ObjectMessageBuilder; import resources.objects.creature.CreatureObject; @@ -399,7 +400,10 @@ public class TangibleObject extends SWGObject implements Serializable { } public boolean isAttackableBy(CreatureObject attacker) { + int pvpStatus = NGECore.getInstance().factionService.calculatePvpStatus(attacker, this); + return (((pvpStatus & PvpStatus.Attackable) == PvpStatus.Attackable) || ((pvpStatus & PvpStatus.Aggressive) == PvpStatus.Aggressive)); + /* CreatureObject creature; if(this instanceof CreatureObject) { @@ -436,6 +440,7 @@ public class TangibleObject extends SWGObject implements Serializable { return true; return getPvPBitmask() == 1 || getPvPBitmask() == 2; + */ } public void showFlyText(OutOfBand outOfBand, float scale, RGB color, int displayType, boolean notifyObservers) { diff --git a/src/services/gcw/FactionService.java b/src/services/gcw/FactionService.java index 4148f969..1835ed8b 100644 --- a/src/services/gcw/FactionService.java +++ b/src/services/gcw/FactionService.java @@ -24,6 +24,7 @@ package services.gcw; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicReference; import main.NGECore; @@ -33,15 +34,15 @@ import org.python.core.Py; import org.python.core.PyObject; import protocol.swg.FactionResponseMessage; - import resources.common.FileUtilities; import resources.common.Opcodes; import resources.datatables.FactionStatus; +import resources.datatables.Options; import resources.datatables.PvpStatus; import resources.objects.creature.CreatureObject; +import resources.objects.mission.MissionObject; import resources.objects.player.PlayerObject; import resources.objects.tangible.TangibleObject; - import engine.clientdata.StfTable; import engine.clients.Client; import engine.resources.common.CRC; @@ -131,27 +132,27 @@ public class FactionService implements INetworkDispatch { } /* - * Returns true if creature2 is an ally of creature1 + * Returns true if target is an ally of object * * Will be useful for NPC AI, so they know who to help and who to be indifferent to. */ - public boolean isFactionAlly(CreatureObject creature1, CreatureObject creature2) { - if (creature1 == null || creature2 == null) { + public boolean isFactionAlly(TangibleObject object, TangibleObject target) { + if (object == null || target == null) { return false; } - String faction1 = creature1.getFaction(); - String faction2 = creature2.getFaction(); + String objectFaction = object.getFaction(); + String targetFaction = target.getFaction(); - if (!isFaction(faction1) || !isFaction(faction2)) { + if (!isFaction(objectFaction) || !isFaction(targetFaction)) { return false; } - if (FileUtilities.doesFileExist("scripts/faction/" + faction1 + ".py")) { - PyObject method = core.scriptService.getMethod("scripts/faction/", faction1, "isAlly"); + if (FileUtilities.doesFileExist("scripts/faction/" + objectFaction + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isAlly"); if (method != null && method.isCallable()) { - return ((method.__call__(Py.java2py(faction2)).asInt() == 1) ? true : false); + return ((method.__call__(Py.java2py(targetFaction)).asInt() == 1) ? true : false); } } @@ -159,27 +160,27 @@ public class FactionService implements INetworkDispatch { } /* - * Returns true if creature2 is an enemy of creature1 + * Returns true if target is an enemy of object * * Will be useful for NPC AI, so they know who to attack and who to be indifferent to. */ - public boolean isFactionEnemy(CreatureObject creature1, CreatureObject creature2) { - if (creature1 == null || creature2 == null) { + public boolean isFactionEnemy(TangibleObject object, TangibleObject target) { + if (object == null || target == null) { return false; } - String faction1 = creature1.getFaction(); - String faction2 = creature2.getFaction(); + String objectFaction = object.getFaction(); + String targetFaction = target.getFaction(); - if (!isFaction(faction1) || !isFaction(faction2)) { + if (!isFaction(objectFaction) || !isFaction(targetFaction)) { return false; } - if (FileUtilities.doesFileExist("scripts/faction/" + faction1 + ".py")) { - PyObject method = core.scriptService.getMethod("scripts/faction/", faction1, "isEnemy"); + if (FileUtilities.doesFileExist("scripts/faction/" + objectFaction + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isEnemy"); if (method != null && method.isCallable()) { - return ((method.__call__(Py.java2py(faction2)).asInt() == 1) ? true : false); + return ((method.__call__(Py.java2py(targetFaction)).asInt() == 1) ? true : false); } } @@ -196,66 +197,139 @@ public class FactionService implements INetworkDispatch { * * This should be used instead of getPvPBitmask where possible, but * should not be used in setPvPBitmask. + * + * *** Updated this so it calculates if even a tangible object + * should see something as attackable (so it works for npcs and turrets). + * + * Also takes into account bounty targets and if it's a pet. */ - /*public int calculatePvpStatus(CreatureObject player, TangibleObject target) { - PlayerObject ghost = (PlayerObject) player.getSlottedObject("ghost"); + public int calculatePvpStatus(TangibleObject object, TangibleObject target) { + PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); - int pvpBitmask = target.getPvPBitmask(); + int pvpBitmask = 0; - // Seefo: Casting target to type CreatureObject as temporary fix. I am unsure whether or not we want to put a factionStatus member inside of TangibleObject. - if (((CreatureObject) target).getFactionStatus() == FactionStatus.Combatant) { - pvpBitmask |= PvpStatus.Enemy; - } - - if (((CreatureObject) target).getFactionStatus() == FactionStatus.SpecialForces) { - pvpBitmask |= PvpStatus.Overt; - - if (target.getSlottedObject("ghost") != null) { - pvpBitmask |= PvpStatus.Enemy; - } + if (object == target) { + pvpBitmask |= PvpStatus.Self; } if (target.getSlottedObject("ghost") != null) { pvpBitmask |= PvpStatus.Player; - - if ((!player.getFaction().equals(target.getFaction()) && - player.getFactionStatus() == FactionStatus.SpecialForces && - ((CreatureObject) target).getFactionStatus() == FactionStatus.SpecialForces) || - core.combatService.areInDuel(player, (CreatureObject) target)) { - pvpBitmask |= (PvpStatus.Attackable | PvpStatus.Aggressive); - } - - if (core.combatService.areInDuel(player, (CreatureObject) target)) { - //pvpBitmask |= PvpStatus.Dueling; - } - + } + + if (target instanceof CreatureObject && ((CreatureObject) target).getOwnerId() > 0) { + target = (TangibleObject) core.objectService.getObject(((CreatureObject) target).getOwnerId()); + } + + if ((target.getPvPBitmask() & PvpStatus.GoingCovert) == PvpStatus.GoingCovert) { + pvpBitmask |= PvpStatus.GoingCovert; + } + + if ((target.getPvPBitmask() & PvpStatus.GoingOvert) == PvpStatus.GoingOvert) { + pvpBitmask |= PvpStatus.GoingOvert; + } + + if (target.getFactionStatus() == FactionStatus.SpecialForces) { + pvpBitmask |= PvpStatus.Overt; + } + + // Everything below assumes target is potentially attackable. + if (!target.getOption(Options.ATTACKABLE)) { return pvpBitmask; } - if (player.getFaction().equals(target.getFaction())) { + if (ghost != null && target.getSlottedObject("ghost") != null && + core.combatService.areInDuel((CreatureObject) object, (CreatureObject) target)) { + pvpBitmask |= (PvpStatus.Attackable | PvpStatus.Aggressive); + } + + if (object.getDefendersList().contains(target)) { + pvpBitmask |= (PvpStatus.Attackable | PvpStatus.Aggressive); + } + + AtomicReference ref = new AtomicReference(0); + + long targetId = target.getObjectID(); + + if (object.getSlottedObject("mission_bag") != null) { + object.getSlottedObject("mission_bag").viewChildren(object, false, false, (mission) -> { + if (((MissionObject) mission).getBountyObjId() == targetId) { + ref.set(PvpStatus.Attackable | PvpStatus.Aggressive); + } + }); + } + + if (ghost != null && ghost.getProfession().contains("smuggler") && + target.getSlottedObject("mission_bag") != null) { + target.getSlottedObject("mission_bag").viewChildren(target, false, false, (mission) -> { + if (((MissionObject) mission).getBountyObjId() == object.getObjectID()) { + ref.set(PvpStatus.Attackable); + } + }); + } + + pvpBitmask |= ref.get(); + + if (target instanceof CreatureObject && ((CreatureObject) target).getTefTime() > 0) { + pvpBitmask |= PvpStatus.TEF; + } + + if (target.getFaction().equals(object.getFaction())) { return pvpBitmask; } - if (target.getOption(Options.ATTACKABLE)) { + if (target.getSlottedObject("ghost") == null && target.getFactionStatus() == FactionStatus.OnLeave) { pvpBitmask |= PvpStatus.Attackable; } if (target.getOption(Options.AGGRESSIVE)) { pvpBitmask |= PvpStatus.Aggressive; - } else { - Integer factionStanding = ghost.getFactionStandingMap().get(target.getFaction()); - - if (factionStanding != null) { - if (((TangibleObject) target).getOption(Options.ATTACKABLE) && factionStanding < 0) { - pvpBitmask |= PvpStatus.Aggressive; + } + + if (object.getFactionStatus() == FactionStatus.OnLeave) { + return pvpBitmask; + } + + if (target.getFactionStatus() >= FactionStatus.Combatant) { + if (ghost != null) { + if (target.getSlottedObject("ghost") == null) { + pvpBitmask |= PvpStatus.Enemy; + + Integer factionStanding = ghost.getFactionStandingMap().get(target.getFaction()); + + if (factionStanding != null) { + if (factionStanding < 0) { + pvpBitmask |= PvpStatus.Aggressive; + } else { + pvpBitmask |= PvpStatus.Attackable; + } + } else { + pvpBitmask |= PvpStatus.Attackable; + } + + return pvpBitmask; + } + } else { + if (isFactionEnemy(object, target)) { + pvpBitmask |= PvpStatus.Attackable | PvpStatus.Enemy; + } + + if (isFactionEnemy(target, object)) { + pvpBitmask |= PvpStatus.Aggressive | PvpStatus.Enemy; } } } + if (target.getFactionStatus() == FactionStatus.SpecialForces) { + if (object.getFactionStatus() == FactionStatus.SpecialForces) { + pvpBitmask |= (PvpStatus.Attackable | PvpStatus.Aggressive | PvpStatus.Enemy); + } + } + return pvpBitmask; - }*/ + } // temp fix until calculatePvpStatus is fixed + /* public int calculatePvpStatus(CreatureObject player, TangibleObject target) { if(target.getSlottedObject("ghost") != null) { @@ -275,6 +349,7 @@ public class FactionService implements INetworkDispatch { } } + */ public Map getFactionMap() { return factionMap;