diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index 448d93e6..7f179230 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -99,7 +99,7 @@ namespace FFXIVClassic_Map_Server.Actors { return AddActorPacket.BuildPacket(actorId, val); } - + public SubPacket CreateNamePacket() { return SetActorNamePacket.BuildPacket(actorId, displayNameId, displayNameId == 0xFFFFFFFF | displayNameId == 0x0 ? customDisplayName : ""); @@ -149,39 +149,11 @@ namespace FFXIVClassic_Map_Server.Actors //spawnPacket.DebugPrintSubPacket(); return spawnPacket; - } - - public SubPacket CreatePositionUpdatePacket(bool forceUpdate = false) - { - int updateMs = 300; - var diffTime = (DateTime.Now - lastMoveUpdate); + } - if (this.target != null) - { - updateMs = 150; - } - - if (forceUpdate || (hasMoved && ((this is Player ) || diffTime.Milliseconds >= updateMs))) - { - hasMoved = (this.positionUpdates != null && this.positionUpdates.Count > 0); - if (hasMoved) - { - var pos = positionUpdates[0]; - - if (this is Character) - ((Character)this).OnPath(pos); - - positionX = pos.X; - positionY = pos.Y; - positionZ = pos.Z; - //Program.Server.GetInstance().mLuaEngine.OnPath(actor, position, positionUpdates) - - positionUpdates.RemoveAt(0); - } - lastMoveUpdate = DateTime.Now; - return MoveActorToPositionPacket.BuildPacket(actorId, playerActorId, positionX, positionY, positionZ, rotation, moveState); - } - return null; + public SubPacket CreatePositionUpdatePacket(uint playerActorId) + { + return MoveActorToPositionPacket.BuildPacket(actorId, playerActorId, positionX, positionY, positionZ, rotation, moveState); } public SubPacket CreateStatePacket() @@ -285,7 +257,7 @@ namespace FFXIVClassic_Map_Server.Actors public SubPacket CreateIsZoneingPacket() { - return SetActorIsZoningPacket.BuildPacket(actorId, false); + return SetActorIsZoningPacket.BuildPacket(actorId, false); } public virtual SubPacket CreateScriptBindPacket(Player player) @@ -293,13 +265,13 @@ namespace FFXIVClassic_Map_Server.Actors return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, classParams); } - public virtual SubPacket CreateScriptBindPacket() + public virtual SubPacket CreateScriptBindPacket() { return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, classParams); } - + public virtual List GetSpawnPackets(Player player, ushort spawnType) - { + { List subpackets = new List(); subpackets.Add(CreateAddActorPacket(8)); subpackets.AddRange(GetEventConditionPackets()); diff --git a/FFXIVClassic Map Server/actors/area/Area.cs b/FFXIVClassic Map Server/actors/area/Area.cs index 69911536..6cc437ba 100644 --- a/FFXIVClassic Map Server/actors/area/Area.cs +++ b/FFXIVClassic Map Server/actors/area/Area.cs @@ -104,6 +104,7 @@ namespace FFXIVClassic_Map_Server.Actors return subpackets; } + // todo: handle instance areas in derived class? (see virtuals) #region Actor Management public void AddActorToZone(Actor actor) @@ -204,12 +205,12 @@ namespace FFXIVClassic_Map_Server.Actors } } - public List GetActorsAroundPoint(float x, float y, int checkDistance) + public virtual List GetActorsAroundPoint(float x, float y, int checkDistance) where T : Actor { checkDistance /= boundingGridSize; - int gridX = (int)x/boundingGridSize; - int gridY = (int)y/boundingGridSize; + int gridX = (int)x / boundingGridSize; + int gridY = (int)y / boundingGridSize; gridX += halfWidth; gridY += halfHeight; @@ -224,7 +225,7 @@ namespace FFXIVClassic_Map_Server.Actors if (gridY >= numYBlocks) gridY = numYBlocks - 1; - List result = new List(); + List result = new List(); lock (mActorBlock) { @@ -232,7 +233,7 @@ namespace FFXIVClassic_Map_Server.Actors { for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++) { - result.AddRange(mActorBlock[gx, gy]); + result.AddRange(mActorBlock[gx, gy].OfType()); } } } @@ -246,11 +247,20 @@ namespace FFXIVClassic_Map_Server.Actors result.RemoveAt(i); } } - return result; } - public List GetActorsAroundActor(Actor actor, int checkDistance) + public virtual List GetActorsAroundPoint(float x, float y, int checkDistance) + { + return GetActorsAroundPoint(x, y, checkDistance); + } + + public virtual List GetActorsAroundActor(Actor actor, int checkDistance) + { + return GetActorsAroundActor(actor, checkDistance); + } + + public virtual List GetActorsAroundActor(Actor actor, int checkDistance) where T : Actor { checkDistance /= boundingGridSize; @@ -270,7 +280,7 @@ namespace FFXIVClassic_Map_Server.Actors if (gridY >= numYBlocks) gridY = numYBlocks - 1; - List result = new List(); + var result = new List(); lock (mActorBlock) { @@ -278,10 +288,11 @@ namespace FFXIVClassic_Map_Server.Actors { for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++) { - result.AddRange(mActorBlock[gx, gy]); + result.AddRange(mActorBlock[gx, gy].OfType()); } } } + //Remove players if isolation zone if (isIsolated) { @@ -327,13 +338,10 @@ namespace FFXIVClassic_Map_Server.Actors { lock (mActorList) { - foreach (Actor a in mActorList.Values) + foreach (Player player in mActorList.Values.OfType()) { - if (a is Player) - { - if (((Player)a).customDisplayName.ToLower().Equals(name.ToLower())) - return (Player)a; - } + if (player.customDisplayName.ToLower().Equals(name.ToLower())) + return player; } return null; } @@ -369,6 +377,7 @@ namespace FFXIVClassic_Map_Server.Actors } // todo: for zones override this to seach contentareas (assuming flag is passed) +<<<<<<< HEAD public virtual List GetAllActors() { lock (mActorList) @@ -378,10 +387,27 @@ namespace FFXIVClassic_Map_Server.Actors { actorList.Add(actor); } +======= + public virtual List GetAllActors() where T : Actor + { + lock (mActorList) + { + List actorList = new List(mActorList.Count); + actorList.AddRange(mActorList.Values.OfType()); +>>>>>>> 84d5eee1fcc284d252b7953a70aebed60b195ee8 return actorList; } } +<<<<<<< HEAD +======= + + public virtual List GetAllActors() + { + return GetAllActors(); + } + +>>>>>>> 84d5eee1fcc284d252b7953a70aebed60b195ee8 public void BroadcastPacketsAroundActor(Actor actor, List packets) { foreach (SubPacket packet in packets) diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs index 4d0d5c35..761d39c7 100644 --- a/FFXIVClassic Map Server/actors/chara/Character.cs +++ b/FFXIVClassic Map Server/actors/chara/Character.cs @@ -10,7 +10,16 @@ using System; namespace FFXIVClassic_Map_Server.Actors { - class Character:Actor + /// Which Character types am I friendly with + enum CharacterTargetingAllegiance + { + /// Friendly to Players + Player, + /// Friendly to BattleNpcs + BattleNpcs + } + + class Character : Actor { public const int SIZE = 0; public const int COLORINFO = 1; @@ -66,6 +75,8 @@ namespace FFXIVClassic_Map_Server.Actors public AIContainer aiContainer; public StatusEffects statusEffects; + public CharacterTargetingAllegiance allegiance; + public Character(uint actorID) : base(actorID) { //Init timer array to "notimer" diff --git a/FFXIVClassic Map Server/actors/chara/ai/AIContainer.cs b/FFXIVClassic Map Server/actors/chara/ai/AIContainer.cs index 094e5412..a0dba867 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/AIContainer.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/AIContainer.cs @@ -88,6 +88,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai this.controller = controller; } + public Controller GetController() + { + return controller; + } + public bool CanChangeState() { return states.Count == 0 || states.Peek().CanInterrupt(); diff --git a/FFXIVClassic Map Server/actors/chara/ai/TargetFind.cs b/FFXIVClassic Map Server/actors/chara/ai/TargetFind.cs index 06752fe2..49af0b78 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/TargetFind.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/TargetFind.cs @@ -5,6 +5,8 @@ using System.Text; using System.Threading.Tasks; using FFXIVClassic_Map_Server.Actors; using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.actors.chara.ai; +using FFXIVClassic_Map_Server.actors.chara.ai.controllers; // port of dsp's ai code https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/ @@ -16,7 +18,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai { None, /// Able to target s even if not in target's party - All, + HitAll, /// Able to target all s in target's party/alliance Alliance, /// Able to target any in target's party/alliance @@ -67,6 +69,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai { private Character owner; private Character target; + private Character masterTarget; // if target is a pet, this is the owner private TargetFindCharacterType findType; private TargetFindFlags findFlags; private TargetFindAOEType aoeType; @@ -95,6 +98,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai this.targets = new List(); } + public List GetTargets() where T : Character + { + return new List(targets.OfType()); + } + + public List GetTargets() + { + return targets; + } + /// /// Call this before /// @@ -128,84 +141,103 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai /// Call SetAOEType before calling this /// Find targets within area set by /// - /// Include pets? - - public void FindWithinArea(Character target, TargetFindFlags flags, bool withPet) + public void FindWithinArea(Character target, TargetFindFlags flags) { + findFlags = flags; // todo: maybe we should keep a snapshot which is only updated on each tick for consistency - // are we creating aoe circles around target or self if ((aoeType & TargetFindAOEType.Circle) != 0 && radiusType != TargetFindAOERadiusType.Self) this.targetPosition = owner.GetPosAsVector3(); else - this.targetPosition = new Vector3(target.positionX, target.positionY, target.positionZ); + this.targetPosition = target.GetPosAsVector3(); - this.findFlags = flags; - if (aoeType == TargetFindAOEType.Box) + masterTarget = TryGetMasterTarget(target) ?? target; + + // todo: should i set this yet or wait til checked if valid target + this.target = target; + + // todo: this is stupid + bool withPet = (flags & TargetFindFlags.Pets) != 0 || masterTarget.allegiance != owner.allegiance; + + if (IsPlayer(owner)) { - FindWithinBox(withPet); + if (masterTarget is Player) + { + findType = TargetFindCharacterType.PlayerToPlayer; + + // todo: handle player parties + if (masterTarget.currentParty != null) + { + if ((findFlags & TargetFindFlags.Alliance) != 0) + AddAllInAlliance(masterTarget, withPet); + else + AddAllInParty(masterTarget, withPet); + } + else + { + AddTarget(masterTarget, withPet); + } + } + else + { + findType = TargetFindCharacterType.PlayerToBattleNpc; + AddAllBattleNpcs(masterTarget, false); + } } - else if (aoeType == TargetFindAOEType.Circle) + else { - FindWithinCircle(withPet); + // todo: this needs checking.. + if (masterTarget is Player || owner.allegiance == CharacterTargetingAllegiance.Player) + findType = TargetFindCharacterType.BattleNpcToPlayer; + else + findType = TargetFindCharacterType.BattleNpcToBattleNpc; + + // todo: configurable pet aoe buff + if (findType == TargetFindCharacterType.BattleNpcToBattleNpc && TryGetMasterTarget(target) != null) + withPet = true; + + // todo: does ffxiv have call for help flag? + //if ((findFlags & TargetFindFlags.HitAll) != 0) + //{ + // AddAllInZone(masterTarget, withPet); + //} + + AddAllInAlliance(target, withPet); + + if (findType == TargetFindCharacterType.BattleNpcToPlayer) + { + if (owner.allegiance == CharacterTargetingAllegiance.Player) + AddAllInZone(masterTarget, withPet); + else + AddAllInHateList(); + } } + } /// /// Find targets within a box using owner's coordinates and target's coordinates as length /// with corners being `extents` yalms to either side of self and target /// - private void FindWithinBox(bool withPet) + private bool IsWithinBox(Character target, bool withPet) { - // todo: loop over party members - if ((findFlags & TargetFindFlags.All) != 0) - { - // if we have flag set to hit all characters in zone, do it + var myPos = owner.GetPosAsVector3(); + var angle = Vector3.GetAngle(myPos, targetPosition); - // todo: make the distance check modifiable - var actors = (findFlags & TargetFindFlags.ZoneWide) != 0 ? owner.zone.GetAllActors() : owner.zone.GetActorsAroundActor(owner, 30); - var myPos = owner.GetPosAsVector3(); - var angle = Vector3.GetAngle(myPos, targetPosition); + // todo: actually check this works.. + var myCorner = myPos.NewHorizontalVector(angle, extents); + var myCorner2 = myPos.NewHorizontalVector(angle, -extents); - // todo: actually check this works.. - var myCorner = myPos.NewHorizontalVector(angle, extents); - var myCorner2 = myPos.NewHorizontalVector(angle, -extents); + var targetCorner = targetPosition.NewHorizontalVector(angle, extents); + var targetCorner2 = targetPosition.NewHorizontalVector(angle, -extents); - var targetCorner = targetPosition.NewHorizontalVector(angle, extents); - var targetCorner2 = targetPosition.NewHorizontalVector(angle, -extents); - - foreach (Character actor in actors) - { - // dont wanna add static actors - if (actor is Player || actor is BattleNpc) - { - if (actor.GetPosAsVector3().IsWithinBox(myCorner2, targetCorner)) - { - if (CanTarget(actor)) - AddTarget(actor, withPet); - } - } - } - } + return target.GetPosAsVector3().IsWithinBox(targetCorner2, myCorner); } - /// - /// Find targets within circle area. - /// As the name implies, it only checks horizontal coords, not vertical - - /// effectively creating cylinder with infinite height - /// - private void FindWithinCircle(bool withPet) + private bool IsWithinCone(Character target, bool withPet) { - var actors = (findFlags & TargetFindFlags.ZoneWide) != 0 ? owner.zone.GetAllActors() : owner.zone.GetActorsAroundActor(owner, 30); - - foreach (Character target in actors) - { - if (target is Player || target is BattleNpc) - { - if (target.GetPosAsVector3().IsWithinCircle(targetPosition, extents)) - AddTarget(target, withPet); - } - } + // todo: + return false; } private void AddTarget(Character target, bool withPet) @@ -220,14 +252,61 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai private void AddAllInParty(Character target, bool withPet) { // todo: + /* + * foreach (var actor in target.currentParty.GetMembers()) + * { + * AddTarget(actor, withPet); + * } + */ + AddTarget(target, withPet); } private void AddAllInAlliance(Character target, bool withPet) { // todo: + /* + * foreach (var actor in target.currentParty.GetAllianceMembers()) + * { + * AddTarget(actor, withPet); + * } + */ + AddTarget(target, withPet); } - public bool CanTarget(Character target) + private void AddAllBattleNpcs(Character target, bool withPet) + { + // 70 is client render distance so we'll go with that + var actors = (findFlags & TargetFindFlags.ZoneWide) != 0 ? owner.zone.GetAllActors() : owner.zone.GetActorsAroundActor(owner, 70); + + // todo: should we look for Characters instead in case player is charmed by BattleNpc + foreach (BattleNpc actor in actors) + { + // todo: + AddTarget(actor, false); + } + } + + private void AddAllInZone(Character target, bool withPet) + { + var actors = owner.zone.GetAllActors(); + foreach (Character actor in actors) + { + AddTarget(actor, withPet); + } + } + + private void AddAllInHateList() + { + if (!(owner is BattleNpc)) + Program.Log.Error($"TargetFind.AddAllInHateList() owner [{owner.actorId}] {owner.customDisplayName} {owner.actorName} is not a BattleNpc"); + + foreach (var hateEntry in ((BattleNpc)owner).hateContainer.GetHateList()) + { + AddTarget(hateEntry.Value.actor, false); + } + } + + public bool CanTarget(Character target, bool withPet = false) { // already targeted, dont target again if (targets.Contains(target)) @@ -237,12 +316,55 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai if ((findFlags & TargetFindFlags.Dead) == 0 && target.IsDead()) return false; - // cant target if player is zoning - if (target is Player && ((Player)target).playerSession.isUpdatesLocked) + bool targetingPlayer = target is Player; + + // cant target if zoning + if (target.isZoning || owner.isZoning || target.zone != owner.zone || targetingPlayer && ((Player)target).playerSession.isUpdatesLocked) return false; - return true; + // hit everything within zone or within aoe region + if ((findFlags & TargetFindFlags.ZoneWide) != 0 || aoeType == TargetFindAOEType.Circle && target.GetPosAsVector3().IsWithinCircle(targetPosition, extents)) + return true; + + if (aoeType == TargetFindAOEType.Cone && IsWithinCone(target, withPet)) + return true; + + if (aoeType == TargetFindAOEType.Box && IsWithinBox(target, withPet)) + return true; + + return false; } + private bool IsPlayer(Character target) + { + if (target is Player) + return true; + + // treat player owned pets as players too + return TryGetMasterTarget(target) is Player; + } + + private Character TryGetMasterTarget(Character target) + { + // if character is a player owned pet, treat as a player + if (target.aiContainer != null) + { + var controller = target.aiContainer.GetController(); + if (controller != null && controller is PetController) + return ((PetController)controller).GetPetMaster(); + } + return null; + } + + private bool IsBattleNpcOwner(Character target) + { + // i know i copied this from dsp but what even + if (!(owner is Player) || target is Player) + return true; + + // todo: check hate list + + return false; + } } } diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/PetController.cs b/FFXIVClassic Map Server/actors/chara/ai/controllers/PetController.cs index dbe7e67f..2ffa3336 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/controllers/PetController.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/controllers/PetController.cs @@ -3,10 +3,70 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using FFXIVClassic_Map_Server.Actors; namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers { - class PetController + class PetController : Controller { + private Character petMaster; + + public PetController(Character owner) + { + this.owner = owner; + this.lastUpdate = Program.Tick; + } + + public override void Update(DateTime tick) + { + // todo: handle player stuff on tick + } + + public override void ChangeTarget(Character target) + { + base.ChangeTarget(target); + } + + public override bool Engage(Character target) + { + // todo: check distance, last swing time, status effects + return true; + } + + public override bool Disengage() + { + // todo: + return true; + } + + public override void Cast(Character target, uint spellId) + { + + } + + public override void Ability(Character target, uint abilityId) + { + + } + + public override void RangedAttack(Character target) + { + + } + + public Character GetPetMaster() + { + return petMaster; + } + + public void SetPetMaster(Character master) + { + petMaster = master; + + if (master is Player) + owner.allegiance = CharacterTargetingAllegiance.Player; + else + owner.allegiance = CharacterTargetingAllegiance.BattleNpcs; + } } } diff --git a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs index b7895e3d..8adaa964 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs @@ -24,6 +24,7 @@ namespace FFXIVClassic_Map_Server.Actors this.aiContainer = new AIContainer(this, new BattleNpcController(this), new PathFind(this), new TargetFind(this)); this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER; this.hateContainer = new HateContainer(this); + this.allegiance = CharacterTargetingAllegiance.BattleNpcs; } } } diff --git a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs index 0fbc0eee..0727217d 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs @@ -388,7 +388,6 @@ namespace FFXIVClassic_Map_Server.Actors player.QueuePacket(PlayBGAnimation.BuildPacket(actorId, animationName)); } - public void Despawn() { zone.DespawnActor(this); diff --git a/FFXIVClassic Map Server/actors/chara/npc/Pet.cs b/FFXIVClassic Map Server/actors/chara/npc/Pet.cs index 1ecaa67f..27e9490e 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/Pet.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/Pet.cs @@ -17,7 +17,7 @@ namespace FFXIVClassic_Map_Server.Actors ushort actorState, uint animationId, string customDisplayName) : base(actorNumber, actorClass, uniqueId, spawnedArea, posX, posY, posZ, rot, actorState, animationId, customDisplayName) { - this.aiContainer = new AIContainer(this, new BattleNpcController(this), new PathFind(this), new TargetFind(this)); + this.aiContainer = new AIContainer(this, new PetController(this), new PathFind(this), new TargetFind(this)); this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER; this.hateContainer = new HateContainer(this); } diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index aeeaf299..60075518 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -243,6 +243,7 @@ namespace FFXIVClassic_Map_Server.Actors lastPlayTimeUpdate = Utils.UnixTimeStampUTC(); this.aiContainer = new AIContainer(this, new PlayerController(this), null, new TargetFind(this)); + allegiance = CharacterTargetingAllegiance.Player; } public List Create0x132Packets() @@ -267,9 +268,9 @@ namespace FFXIVClassic_Map_Server.Actors * Unknown - Bool * Unknown - Number * Unknown - Bool - * Timer Array - 20 Number - */ - + * Timer Array - 20 Number + */ + public override SubPacket CreateScriptBindPacket(Player requestPlayer) { List lParams; @@ -285,7 +286,8 @@ namespace FFXIVClassic_Map_Server.Actors ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams).DebugPrintSubPacket(); - return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams); + + return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams); } public override List GetSpawnPackets(Player requestPlayer, ushort spawnType) @@ -294,21 +296,21 @@ namespace FFXIVClassic_Map_Server.Actors subpackets.Add(CreateAddActorPacket(8)); if (IsMyPlayer(requestPlayer.actorId)) subpackets.AddRange(Create0x132Packets()); - subpackets.Add(CreateSpeedPacket()); + subpackets.Add(CreateSpeedPacket()); subpackets.Add(CreateSpawnPositonPacket(this, spawnType)); subpackets.Add(CreateAppearancePacket()); subpackets.Add(CreateNamePacket()); subpackets.Add(_0xFPacket.BuildPacket(actorId)); subpackets.Add(CreateStatePacket()); subpackets.Add(CreateIdleAnimationPacket()); - subpackets.Add(CreateInitStatusPacket()); - subpackets.Add(CreateSetActorIconPacket()); + subpackets.Add(CreateInitStatusPacket()); + subpackets.Add(CreateSetActorIconPacket()); subpackets.Add(CreateIsZoneingPacket()); subpackets.AddRange(CreatePlayerRelatedPackets(requestPlayer.actorId)); subpackets.Add(CreateScriptBindPacket(requestPlayer)); return subpackets; } - + public List CreatePlayerRelatedPackets(uint requestingPlayerActorId) { List subpackets = new List(); @@ -319,9 +321,9 @@ namespace FFXIVClassic_Map_Server.Actors if (currentTitle != 0) subpackets.Add(SetPlayerTitlePacket.BuildPacket(actorId, currentTitle)); - if (currentJob != 0) - subpackets.Add(SetCurrentJobPacket.BuildPacket(actorId, currentJob)); - + if (currentJob != 0) + subpackets.Add(SetCurrentJobPacket.BuildPacket(actorId, currentJob)); + if (IsMyPlayer(requestingPlayerActorId)) { subpackets.Add(SetSpecialEventWorkPacket.BuildPacket(actorId)); @@ -347,7 +349,7 @@ namespace FFXIVClassic_Map_Server.Actors return subpackets; } - + public override List GetInitPackets() { ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("/_init", this); @@ -512,8 +514,8 @@ namespace FFXIVClassic_Map_Server.Actors QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1)); QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId)); - - QueuePackets(GetSpawnPackets(this, spawnType)); + + QueuePackets(GetSpawnPackets(this, spawnType)); //GetSpawnPackets(actorId, spawnType).DebugPrintPacket(); #region Inventory & Equipment @@ -523,17 +525,17 @@ namespace FFXIVClassic_Map_Server.Actors inventories[Inventory.KEYITEMS].SendFullInventory(); inventories[Inventory.BAZAAR].SendFullInventory(); inventories[Inventory.MELDREQUEST].SendFullInventory(); - inventories[Inventory.LOOT].SendFullInventory(); - equipment.SendFullEquipment(false); + inventories[Inventory.LOOT].SendFullInventory(); + equipment.SendFullEquipment(false); playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId)); #endregion - playerSession.QueuePacket(GetInitPackets()); + playerSession.QueuePacket(GetInitPackets()); List areaMasterSpawn = zone.GetSpawnPackets(); List debugSpawn = world.GetDebugActor().GetSpawnPackets(); List worldMasterSpawn = world.GetActor().GetSpawnPackets(); - + playerSession.QueuePacket(areaMasterSpawn); playerSession.QueuePacket(debugSpawn); playerSession.QueuePacket(worldMasterSpawn); @@ -551,15 +553,15 @@ namespace FFXIVClassic_Map_Server.Actors QueuePacket(SetPlayerItemStoragePacket.BuildPacket(actorId)); } - if (zone.GetWeatherDirector() != null) - { + if (zone.GetWeatherDirector() != null) + { playerSession.QueuePacket(zone.GetWeatherDirector().GetSpawnPackets()); } foreach (Director director in ownedDirectors) { - QueuePackets(director.GetSpawnPackets()); + QueuePackets(director.GetSpawnPackets()); QueuePackets(director.GetInitPackets()); } @@ -592,8 +594,8 @@ namespace FFXIVClassic_Map_Server.Actors public bool IsMyPlayer(uint otherActorId) { - return actorId == otherActorId; - } + return actorId == otherActorId; + } public void QueuePacket(SubPacket packet) { @@ -601,7 +603,7 @@ namespace FFXIVClassic_Map_Server.Actors } public void QueuePackets(List packets) - { + { playerSession.QueuePacket(packets); } @@ -1141,16 +1143,16 @@ namespace FFXIVClassic_Map_Server.Actors } public void MarkGuildleve(uint id, bool abandoned, bool completed) - { - if (HasGuildleve(id)) + { + if (HasGuildleve(id)) { for (int i = 0; i < work.guildleveId.Length; i++) { if (work.guildleveId[i] == id) { work.guildleveChecked[i] = completed; - work.guildleveDone[i] = abandoned; - Database.MarkGuildleve(this, id, abandoned, completed); + work.guildleveDone[i] = abandoned; + Database.MarkGuildleve(this, id, abandoned, completed); SendGuildleveMarkClientUpdate(i); } } @@ -1426,9 +1428,8 @@ namespace FFXIVClassic_Map_Server.Actors private void SendGuildleveMarkClientUpdate(int slot) { - ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("work/guildleve", this); - propPacketUtil.AddProperty(String.Format("work.guildleveDone[{0}]", slot)); - propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", slot)); + ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("work/guildleve", this); + propPacketUtil.AddProperty(String.Format("work.guildleveId[{0}]", slot)); QueuePackets(propPacketUtil.Done()); } @@ -1447,16 +1448,16 @@ namespace FFXIVClassic_Map_Server.Actors } } - public void SendDirectorPackets(Director director) - { + public void SendDirectorPackets(Director director) + { QueuePackets(director.GetSpawnPackets()); QueuePackets(director.GetInitPackets()); } public void RemoveDirector(Director director) - { - if (ownedDirectors.Contains(director)) - { + { + if (ownedDirectors.Contains(director)) + { QueuePacket(RemoveActorPacket.BuildPacket(director.actorId)); ownedDirectors.Remove(director); director.RemoveMember(this); diff --git a/FFXIVClassic Map Server/dataobjects/Session.cs b/FFXIVClassic Map Server/dataobjects/Session.cs index fe07c401..027223b6 100644 --- a/FFXIVClassic Map Server/dataobjects/Session.cs +++ b/FFXIVClassic Map Server/dataobjects/Session.cs @@ -83,7 +83,7 @@ namespace FFXIVClassic_Map_Server.dataobjects playerActor.rotation = rot; playerActor.moveState = moveState; - GetActor().zone.UpdateActorPosition(GetActor()); + GetActor().GetZone().UpdateActorPosition(GetActor()); playerActor.QueuePositionUpdate(new Vector3(x,y,z)); } diff --git a/FFXIVClassic Map Server/lua/LuaEngine.cs b/FFXIVClassic Map Server/lua/LuaEngine.cs index 428f9c89..f79b7593 100644 --- a/FFXIVClassic Map Server/lua/LuaEngine.cs +++ b/FFXIVClassic Map Server/lua/LuaEngine.cs @@ -387,8 +387,8 @@ namespace FFXIVClassic_Map_Server.lua } else CallLuaFunction(player, target, "onEventStarted", false, LuaUtils.CreateLuaParamObjectList(lparams)); - } - + } + public DynValue ResolveResume(Actor actor, Coroutine coroutine, DynValue value) { var isPlayer = actor is Player;