diff --git a/scripts/commands/pvp.py b/scripts/commands/pvp.py index 93e9051b..0155c528 100644 --- a/scripts/commands/pvp.py +++ b/scripts/commands/pvp.py @@ -1,74 +1,72 @@ from resources.objects.creature import CreatureObject -from protocol.swg import UpdatePVPStatusMessage +from resources.common import PvpStatus +from resources.common import FactionStatus import sys +import time def setup(): return def run(core, actor, target, commandString): - actorFaction = actor.getFaction() - actorStatus = actor.getFactionStatus() - pvpStatus = UpdatePVPStatusMessage(actor.getObjectId()) - - if commandString == ('imperial') and actorFaction != "imperial": - actor.setFaction('imperial') - return - - if commandString == ('rebel') and actorFaction != "rebel": - actor.setFaction('rebel') - return - - if commandString == ('neutral') and actorFaction != "neutral": - actor.setFaction('neutral') - return - - if actorStatus == 0 and actorFaction == "imperial": - actor.setFactionStatus(1) - #print ("FactionStatus: " + str(actor.getFactionStatus())) - actor.sendSystemMessage('You are no longer On Leave.', 0) - return + faction = actor.getFaction() + factionStatus = actor.getFactionStatus() - if actorStatus == 0 and actorFaction == "rebel": - actor.setFactionStatus(1) - #print ("FactionStatus: " + str(actor.getFactionStatus())) - actor.sendSystemMessage('You are no longer On Leave.', 0) - return + if actor.getPvpStatus(PvpStatus.GoingOvert) or actor.getPvpStatus(PvpStatus.GoingCovert): + actor.sendSystemMessage('@faction_recruiter:pvp_status_changing', 0) + return - if actorStatus == 1 and actorFaction == "imperial": - actor.setFactionStatus(2) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial) - pvpStatus.setStatus(55) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - if actorStatus == 1 and actorFaction == "rebel": - actor.setFactionStatus(2) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel) - pvpStatus.setStatus(55) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - if actorStatus == 2 and actorFaction == "imperial": - actor.setFactionStatus(1) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial) - pvpStatus.setStatus(16) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - if actorStatus == 2 and actorFaction == "rebel": - actor.setFactionStatus(1) - pvpStatus.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel) - pvpStatus.setStatus(16) - actor.notifyObservers(pvpStatus.serialize(), True) - actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) - print ("FactionStatus: " + str(actor.getFactionStatus())) - return - - - return \ No newline at end of file + if commandString != '' and commandString != faction: + if commandString == 'rebel' or commandString == 'imperial' or commandString == 'neutral': + actor.sendSystemMessage('@faction_recruiter:sui_resig_complete_in_5', 0) + + if actor.getFactionStatus() == FactionStatus.SpecialForces: + actor.setPvpStatus(PvpStatus.GoingCovert, True) + time.sleep(300) + + actor.setPvpStatus(PvpStatus.GoingCovert | PvpStatus.Overt | PvpStatus.Attackable | PvpStatus.Aggressive | PvpStatus.Enemy, False) + actor.setFactionStatus(FactionStatus.OnLeave) + + if actor.getFaction() != '' and actor.getFaction() != 'neutral': + time.sleep(1) + actor.setFaction('') + actor.sendSystemMessage('@faction_recruiter:resign_complete', 0) + + + time.sleep(1) + actor.setFaction(commandString) + return + + if faction == 'neutral' or faction == '': + actor.sendSystemMessage('@faction_recruiter:not_aligned', 0) + return + + if factionStatus == FactionStatus.OnLeave: + actor.sendSystemMessage('@faction_recruiter:on_leave_to_covert', 0) + actor.setPvpStatus(PvpStatus.GoingCovert, True) + time.sleep(1) + actor.setFactionStatus(FactionStatus.Combatant) + actor.setPvpStatus(PvpStatus.GoingCovert, False) + actor.setPvpStatus(PvpStatus.Enemy, True) + actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) + return + + if factionStatus == FactionStatus.Combatant: + actor.sendSystemMessage('@faction_recruiter:covert_to_overt', 0) + actor.setPvpStatus(PvpStatus.GoingOvert, True) + time.sleep(30) + actor.setFactionStatus(FactionStatus.SpecialForces) + actor.setPvpStatus(PvpStatus.GoingOvert, False) + actor.setPvpStatus(PvpStatus.Overt | PvpStatus.Attackable | PvpStatus.Aggressive, True) + actor.sendSystemMessage('@faction_recruiter:overt_complete', 0) + return + + if factionStatus == FactionStatus.SpecialForces: + actor.sendSystemMessage('@faction_recruiter:overt_to_covert', 0) + actor.setPvpStatus(PvpStatus.GoingCovert, True) + time.sleep(300) + actor.setFactionStatus(FactionStatus.Combatant) + actor.setPvpStatus(PvpStatus.GoingCovert | PvpStatus.Overt | PvpStatus.Attackable | PvpStatus.Aggressive, False) + actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) + return + + return diff --git a/src/resources/common/Options.java b/src/resources/common/Options.java new file mode 100644 index 00000000..136c7462 --- /dev/null +++ b/src/resources/common/Options.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.common; + +public class Options { + + // Any uncommented ones are confirmed correct for NGE with detailed analysis + + public static int NONE = 0; + public static int SPACE_ATTACKABLE = 1; // Ships that are attackable in space. Includes everything except stations and asteroids so far + public static int USABLE = 2; // Vendors, collections (hand icon) + public static int INSURED = 4; // Unused in NGE + public static int CONVERSABLE = 8; // Conversable on ground / commable in space + //public static int FOLLOWINGWAYPOINT = 16; // Uncertain, could be "frozen" flag or "alert" flag or other. Seen on rare occasions on NPCs + public static int SOCKETED = 32; // Object has sockets + public static int AGGRESSIVE = 64; // Always aggressive no matter what regardless of faction standing. + public static int ATTACKABLE = 128; // Attackable + public static int INVULNERABLE = 256; // No HAM + public static int DISABLED = 512; // Disabled Vehicle + //public static int CRAFTED = 1024; // Wearable TANO objects. Isn't used for WEAOs (weapons), it's just for identifying if a TANO is a wearable probably as that's where this is seen. Also seen on naboo small house deed however... Could also be "crafted items" + public static int QUEST = 2048; // Quest icon + public static int MOUNT = 4096; // Vehicle and creature mounts + public static int SERIAL = 8192; // Has serial number + //public static int UNKNOWN = 16384; // Seen being requested by the client in objcontroller 0x02AB but probably not relevant + public static int PILOT = 32768; // Pilot trainers, chassis dealers + //public static int UNKNOWN = 65536; + //public static int UNKNOWN = 131072; + //public static int UNKNOWN = 262144; + //public static int UNKNOWN = 524288; + //public static int UNKNOWN = 1048576; + //public static int UNKNOWN = 2097152; + //public static int UNKNOWN = 4194304; + public static int STARTER_SHIP = 8388508; // Seen on player scyk fighters, but no others. Could also mean SPACE_OVERT + +} diff --git a/src/resources/common/PvpStatus.java b/src/resources/common/PvpStatus.java index 18365a58..e668ba56 100644 --- a/src/resources/common/PvpStatus.java +++ b/src/resources/common/PvpStatus.java @@ -23,6 +23,7 @@ package resources.common; public class PvpStatus { + public static int None = 0; public static int Attackable = 1; public static int Aggressive = 2; public static int Overt = 4; @@ -30,7 +31,7 @@ public class PvpStatus { public static int Player = 16; public static int Enemy = 32; public static int GoingOvert = 64; - public static int GoingCombatant = 128; + public static int GoingCovert = 128; public static int Dueling = 256; } diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 0f5d71bf..5ce2cfbf 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -97,14 +97,8 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.put(getAsciiString(creature.getStfName())); if (creature.getCustomName() == null) { creature.setCustomName(""); }//Not all CreatureObjects have CustomName (Shuttles) buffer.put(getUnicodeString(creature.getCustomName())); - buffer.putInt(0x000F4240); // unk - String factionCRC = creature.getFaction(); - if(factionCRC == null) - buffer.putInt(0); - else if(factionCRC.equals("neutral")) - buffer.putInt(0); - else - buffer.putInt(CRC.StringtoCRC(factionCRC)); + buffer.putInt(0x000F4240); // volume + buffer.putInt(CRC.StringtoCRC(creature.getFaction())); buffer.putInt(creature.getFactionStatus()); @@ -119,7 +113,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(1); buffer.putInt(0); // TANO Data buffer.putInt(0); - buffer.putInt(0x80); // 0x80 = Player, 0x08 = Quest NPC, + buffer.putInt(creature.getOptionsBitmask()); // 0x80 = Player, 0x08 = Quest NPC, buffer.putInt(creature.getIncapTimer()); buffer.putInt(0); buffer.putInt(0x3A98); diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 23307378..14a389e0 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -31,8 +31,8 @@ import org.apache.mina.core.buffer.IoBuffer; import protocol.swg.ChatSystemMessage; import protocol.swg.ObjControllerMessage; import protocol.swg.PlayMusicMessage; -import protocol.swg.UpdatePVPStatusMessage; import protocol.swg.UpdatePostureMessage; +import protocol.swg.UpdatePVPStatusMessage; import protocol.swg.objectControllerObjects.Animation; import protocol.swg.objectControllerObjects.Posture; @@ -101,7 +101,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { // CREO6 private byte combatFlag = 0; - private short level = 1; + private short level = -1; private int grantedHealth = 0; private String currentAnimation; private String moodAnimation; @@ -257,7 +257,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } - + + @Override + public int getOptionsBitmask() { + synchronized(objectMutex) { + return optionsBitmask; + } + } + @Override public void setOptionsBitmask(int optionBitmask) { synchronized(objectMutex) { @@ -269,6 +276,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { notifyObservers(optionDelta, true); } + + public void addOption(int option) { + setOptionsBitmask(getOptionsBitmask() & option); + } + + public void removeOption(int option) { + setOptionsBitmask(getOptionsBitmask() |~ option); + } public byte getPosture() { synchronized(objectMutex) { @@ -294,10 +309,8 @@ public class CreatureObject extends TangibleObject implements IPersistent { this.faction = faction; } - IoBuffer factionDelta = messageBuilder.buildFactionDelta(faction); - - notifyObservers(factionDelta, true); - + notifyObservers(messageBuilder.buildFactionDelta(faction), true); + setPvpStatus(0, true); } public int getFactionStatus() { @@ -311,10 +324,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { this.factionStatus = factionStatus; } - IoBuffer factionStatusDelta = messageBuilder.buildFactionStatusDelta(factionStatus); - - notifyObservers(factionStatusDelta, true); - + notifyObservers(messageBuilder.buildFactionStatusDelta(factionStatus), true); } public float getHeight() { @@ -925,33 +935,48 @@ public class CreatureObject extends TangibleObject implements IPersistent { //destination.getSession().write(upm.serialize()); if(destination != getClient()) { - UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()); + + /* if (factionStatus == 1 && faction == "imperial") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial); upvpm.setStatus(16); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); } if (factionStatus == 1 && faction == "rebel") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel); upvpm.setStatus(16); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); } if (factionStatus == 2 && faction == "imperial") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Imperial); upvpm.setStatus(55); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(39); + if (getOwnerId() != 0) upvpm.setStatus(295); } if (factionStatus == 2 && faction == "rebel") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Rebel); upvpm.setStatus(55); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(39); + if (getOwnerId() != 0) upvpm.setStatus(295); } if(factionStatus == 0 && faction == "neutral") { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); upvpm.setStatus(16); - } - else { + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); + } else { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); upvpm.setStatus(16); + if ((getOptionsBitmask() & 128) == 128) upvpm.setStatus(0); + if (getOwnerId() != 0) upvpm.setStatus(256); } + */ + destination.getSession().write(upvpm.serialize()); } } @@ -1268,4 +1293,16 @@ public class CreatureObject extends TangibleObject implements IPersistent { return this.staticNPC = staticNPC; } + @Override + public void setPvPBitmask(int pvpBitmask) { + super.setPvPBitmask(pvpBitmask); + notifyObservers(new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()), false); + } + + @Override + public void setPvpStatus(int pvpBitmask, boolean add) { + super.setPvpStatus(pvpBitmask, add); + notifyObservers(new UpdatePVPStatusMessage(getObjectID(), getPvPBitmask(), getFaction()), false); + } + } diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 92b54e4e..3693b21c 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -67,6 +67,9 @@ public class TangibleObject extends SWGObject { private int respawnTime = 0; private Point3D spawnCoordinates = new Point3D(0, 0, 0); + @NotPersistent + private TangibleObject killer = null; + public TangibleObject(long objectID, Planet planet, String template) { super(objectID, planet, new Point3D(0, 0, 0), new Quaternion(1, 0, 1, 0), template); messageBuilder = new TangibleMessageBuilder(this); @@ -153,6 +156,24 @@ public class TangibleObject extends SWGObject { } } + public boolean getPvpStatus(int pvpStatus) { + synchronized(objectMutex) { + return ((pvpBitmask & pvpStatus) != 0); + } + } + + public void setPvpStatus(int pvpBitmask, boolean add) { + synchronized(objectMutex) { + if (pvpBitmask != 0) { + if (add) { + this.pvpBitmask |= pvpBitmask; + } else { + this.pvpBitmask &= ~pvpBitmask; + } + } + } + } + public String getFaction() { synchronized(objectMutex) { return faction; @@ -278,6 +299,18 @@ public class TangibleObject extends SWGObject { } } + public TangibleObject getKiller() { + synchronized(objectMutex) { + return killer; + } + } + + public void setKiller(TangibleObject killer) { + synchronized(objectMutex) { + this.killer = killer; + } + } + @Override public void sendBaselines(Client destination) { diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 050b6ab7..d629d31f 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -38,6 +38,7 @@ import engine.resources.common.CRC; import engine.resources.container.CreatureContainerPermissions; import engine.resources.container.CreaturePermissions; import engine.resources.database.DatabaseConnection; +import engine.resources.objects.SWGObject; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; import engine.resources.service.INetworkDispatch; @@ -219,6 +220,7 @@ public class CharacterService implements INetworkDispatch { object.setBankCredits(1000); //object.setPosition(new Point3D(0, 0, 0)); object.setOrientation(new Quaternion(1, 0, 0, 0)); + object.setLevel((short) 1); float luck = (((((float) (core.scriptService.getMethod("scripts/roadmap/", clientCreateCharacter.getProfession(), "getLuck").__call__().asInt()) + (core.scriptService.getMethod("scripts/roadmap/", object.getStfName(), "getLuck").__call__().asInt())) / ((float) 90)) * ((float) object.getLevel())) - ((float) object.getSkillModBase("luck"))); float precision = (((((float) (core.scriptService.getMethod("scripts/roadmap/", clientCreateCharacter.getProfession(), "getPrecision").__call__().asInt()) + (core.scriptService.getMethod("scripts/roadmap/", object.getStfName(), "getPrecision").__call__().asInt())) / ((float) 90)) * ((float) object.getLevel())) - ((float) object.getSkillModBase("precision"))); float strength = (((((float) (core.scriptService.getMethod("scripts/roadmap/", clientCreateCharacter.getProfession(), "getStrength").__call__().asInt()) + (core.scriptService.getMethod("scripts/roadmap/", object.getStfName(), "getStrength").__call__().asInt())) / ((float) 90)) * ((float) object.getLevel())) - ((float) object.getSkillModBase("strength"))); @@ -301,7 +303,7 @@ public class CharacterService implements INetworkDispatch { session.write(core.loginService.getLoginClusterStatus().serialize()); session.write(success.serialize()); - session.write((new ClientMfdStatusUpdateMessage((float) 2, "/GroundHUD.MFDStatus.vsp.role.targetLevel")).serialize()); + session.write((new ClientMfdStatusUpdateMessage((float) 2, "/GroundHUD.MFDStatus.vsp.role.targetLevel")).serialize()); } });