/// <inheritdoc /> protected override Task HandleMessage(IPeerSessionMessageContext <GameServerPacketPayload> context, ClientMovementDataUpdateRequest payload, NetworkEntityGuid guid) { try { IMovementGenerator <GameObject> generator = MovementGenerator.RetrieveEntity(guid); IMovementData movementData = MovementDataMap.RetrieveEntity(guid); PositionChangeMovementData changeMovementData = BuildPositionChangeMovementData(payload, generator, movementData); MovementDataMap.ReplaceObject(guid, changeMovementData); IActorRef playerActorRef = ActorReferenceMappable.RetrieveEntity(guid); playerActorRef.TellSelf(new PlayerMovementStateChangedMessage(changeMovementData.Direction)); //If the generator is running, we should use its initial position instead of the last movement data's position. MovementGenerator.ReplaceObject(guid, BuildCharacterControllerMovementGenerator(guid, changeMovementData, generator, movementData)); } catch (Exception e) { if (Logger.IsErrorEnabled) { Logger.Error($"Failed to update MovementData for GUID: {guid} Reason: {e.Message}"); } throw; } return(Task.CompletedTask); }
void Mutate(MovementGenerator m, MovementSlot _slot) { int slot = (int)_slot; MovementGenerator curr = Impl[slot]; if (curr != null) { Impl[slot] = null; // in case a new one is generated in this slot during directdelete if (_top == slot && Convert.ToBoolean(_cleanFlag & MMCleanFlag.UPDATE)) { DelayedDelete(curr); } else { DirectDelete(curr); } } else if (_top < slot) { _top = slot; } Impl[slot] = m; if (_top > slot) { _needInit[slot] = true; } else { _needInit[slot] = false; m.Initialize(_owner); } }
/// <inheritdoc /> protected override Task HandleMessage(IPeerSessionMessageContext <GameServerPacketPayload> context, ClientRotationDataUpdateRequest payload, NetworkEntityGuid guid) { try { IMovementGenerator <GameObject> generator = MovementGenerator.RetrieveEntity(guid); IMovementData movementData = MovementDataMap.RetrieveEntity(guid); //TODO: This is a temporary hack, we nee d abetter solluition if (movementData is PositionChangeMovementData posChangeMoveDat) { Vector2 direction = posChangeMoveDat.Direction; //TODO: Sanity check position sent. //TODO: Sanity check timestamp MovementDataMap.ReplaceObject(guid, new PositionChangeMovementData(payload.TimeStamp, payload.ClientCurrentPosition, direction, payload.Rotation)); } else { throw new NotImplementedException($"TODO: Implement rotation when dealing with: {movementData.GetType().Name} type movement."); } OnPlayerRotationChanged?.Invoke(this, new PlayerRotiationChangeEventArgs(guid, payload.Rotation)); } catch (Exception e) { if (Logger.IsErrorEnabled) { Logger.Error($"Failed to update MovementData for GUID: {guid} Reason: {e.Message}"); } throw; } return(Task.CompletedTask); }
void DirectExpire(bool reset) { if (size() > 1) { MovementGenerator curr = top(); pop(); DirectDelete(curr); } while (top() == null) { --_top; } if (empty()) { Initialize(); } else if (needInitTop()) { InitTop(); } else if (reset) { top().Reset(_owner); } }
public void GeneratesRandomMovement() { MovementGenerator cpu = new MovementGenerator(); Movement generatedMovement = cpu.GenerateMovement(); Assert.IsNotNull(generatedMovement); Assert.IsInstanceOf <Movement> (generatedMovement); }
void DirectDelete(MovementGenerator curr) { if (isStatic(curr)) { return; } curr.Finalize(_owner); }
public void SetUp() { ui = new MyUITest(); displayer = Substitute.For <ScoreDisplayer> (); cpu = Substitute.For <MovementGenerator> (); cpu.GenerateMovement().Returns(new Rock()); game = new Game(ui, displayer, cpu); }
public void UpdateMotion(uint diff) { lock (locker) { if (_owner == null) { return; } if (_owner.HasUnitState(UnitState.Root | UnitState.Stunned)) // what about UNIT_STATE_DISTRACTED? Why is this not included? { return; } _cleanFlag |= MMCleanFlag.UPDATE; if (top() != null && !top().Update(_owner, diff)) { _cleanFlag &= ~MMCleanFlag.UPDATE; MovementExpired(); } else { _cleanFlag &= ~MMCleanFlag.UPDATE; } if (_expList != null) { for (var i = 0; i < _expList.Count; ++i) { MovementGenerator mg = _expList[i]; DirectDelete(mg); } _expList = null; if (empty()) { Initialize(); } else if (needInitTop()) { InitTop(); } else if (Convert.ToBoolean(_cleanFlag & MMCleanFlag.RESET)) { top().Reset(_owner); } _cleanFlag &= ~MMCleanFlag.RESET; } } // probably not the best place to pu this but im not really sure where else to put it. //_owner->UpdateUnderwaterState(_owner->GetMap(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); }
void DelayedClean() { while (size() > 1) { MovementGenerator curr = top(); pop(); if (curr != null) { DelayedDelete(curr); } } }
public MotionMaster(Unit unit) { Impl = new MovementGenerator[(int)MovementSlot.Max]; _needInit = new bool[(int)MovementSlot.Max]; _expList = null; _top = -1; _cleanFlag = MMCleanFlag.NONE; _owner = unit; for (byte i = 0; i < (int)MovementSlot.Max; ++i) { Impl[i] = null; _needInit[i] = true; } }
void DelayedExpire() { if (size() > 1) { MovementGenerator curr = top(); pop(); DelayedDelete(curr); } while (top() == null) { --_top; } }
void DelayedDelete(MovementGenerator curr) { Log.outError("Unit (Entry {0}) is trying to delete its updating MG (Type {1})!", _owner.GetEntry(), curr.GetMovementGeneratorType()); if (isStatic(curr)) { return; } if (_expList == null) { _expList = new List <MovementGenerator>(); } _expList.Add(curr); }
public void Initialize() { // clear ALL movement generators (including default) while (!empty()) { MovementGenerator curr = top(); pop(); if (curr != null) { DirectDelete(curr); } } InitDefault(); }
void DirectClean(bool reset) { while (size() > 1) { MovementGenerator curr = top(); pop(); if (curr != null) { DirectDelete(curr); } } if (needInitTop()) { InitTop(); } else if (reset) { top().Reset(_owner); } }
public void SetEscortPaused(bool on) { if (!HasEscortState(EscortState.Escorting)) { return; } if (on) { AddEscortState(EscortState.Paused); MovementGenerator movementGenerator = me.GetMotionMaster().GetCurrentMovementGenerator(MovementSlot.Default); if (movementGenerator != null) { movementGenerator.Pause(0); } } else { RemoveEscortState(EscortState.Paused); _resume = true; } }
/// <inheritdoc /> protected override Task HandleMessage(IPeerSessionMessageContext <GameServerPacketPayload> context, ClientSetClickToMovePathRequestPayload payload, NetworkEntityGuid guid) { try { IMovementGenerator <GameObject> generator = MovementGenerator.RetrieveEntity(guid); IMovementData movementData = MovementDataMap.RetrieveEntity(guid); PathBasedMovementData changeMovementData = BuildPathData(payload, generator, movementData, guid); //If it doesn't have more one point reject it if (changeMovementData.MovementPath.Count < 2) { return(Task.CompletedTask); } MovementDataMap.ReplaceObject(guid, changeMovementData); IActorRef playerActorRef = ActorReferenceMappable.RetrieveEntity(guid); Vector3 direction3D = (changeMovementData.MovementPath[1] - changeMovementData.MovementPath[0]); Vector2 direction2D = new Vector2(direction3D.x, direction3D.z).normalized; playerActorRef.TellSelf(new PlayerMovementStateChangedMessage(direction2D)); //If the generator is running, we should use its initial position instead of the last movement data's position. MovementGenerator.ReplaceObject(guid, new PathMovementGenerator(changeMovementData)); } catch (Exception e) { if (Logger.IsErrorEnabled) { Logger.Error($"Failed to update MovementData for GUID: {guid} Reason: {e.Message}"); } throw; } return(Task.CompletedTask); }
public Game(IUIEventDispatcher ui, ScoreDisplayer displayer, MovementGenerator cpu) { ui.PlayerMovementSelected += OnPlayerMovementSelected; movementGenerator = cpu; this.displayer = displayer; }
public override void UpdateAI(uint diff) { //Waypoint Updating if (HasEscortState(EscortState.Escorting) && !me.IsEngaged() && !HasEscortState(EscortState.Returning)) { if (_pauseTimer <= diff) { if (!HasEscortState(EscortState.Paused)) { _pauseTimer = 0; if (_ended) { _ended = false; me.GetMotionMaster().MoveIdle(); if (_despawnAtEnd) { Log.outDebug(LogFilter.ScriptsAi, $"EscortAI::UpdateAI: reached end of waypoints, despawning at end ({me.GetGUID()})"); if (_returnToStart) { Position respawnPosition = new(); float orientation; me.GetRespawnPosition(out respawnPosition.posX, out respawnPosition.posY, out respawnPosition.posZ, out orientation); respawnPosition.SetOrientation(orientation); me.GetMotionMaster().MovePoint(EscortPointIds.Home, respawnPosition); Log.outDebug(LogFilter.ScriptsAi, $"EscortAI::UpdateAI: returning to spawn location: {respawnPosition} ({me.GetGUID()})"); } else if (_instantRespawn) { me.Respawn(); } else { me.DespawnOrUnsummon(); } } Log.outDebug(LogFilter.ScriptsAi, $"EscortAI::UpdateAI: reached end of waypoints ({me.GetGUID()})"); RemoveEscortState(EscortState.Escorting); return; } if (!_started) { _started = true; me.GetMotionMaster().MovePath(_path, false); } else if (_resume) { _resume = false; MovementGenerator movementGenerator = me.GetMotionMaster().GetCurrentMovementGenerator(MovementSlot.Default); if (movementGenerator != null) { movementGenerator.Resume(0); } } } } else { _pauseTimer -= diff; } } //Check if player or any member of his group is within range if (_despawnAtFar && HasEscortState(EscortState.Escorting) && !_playerGUID.IsEmpty() && !me.IsEngaged() && !HasEscortState(EscortState.Returning)) { if (_playerCheckTimer <= diff) { if (!IsPlayerOrGroupInRange()) { Log.outDebug(LogFilter.ScriptsAi, $"EscortAI::UpdateAI: failed because player/group was to far away or not found ({me.GetGUID()})"); bool isEscort = false; CreatureData creatureData = me.GetCreatureData(); if (creatureData != null) { isEscort = (WorldConfig.GetBoolValue(WorldCfg.RespawnDynamicEscortNpc) && creatureData.spawnGroupData.flags.HasAnyFlag(SpawnGroupFlags.EscortQuestNpc)); } if (_instantRespawn) { if (!isEscort) { me.DespawnOrUnsummon(0, TimeSpan.FromSeconds(1)); } else { me.GetMap().Respawn(SpawnObjectType.Creature, me.GetSpawnId()); } } else { me.DespawnOrUnsummon(); } return; } _playerCheckTimer = 1000; } else { _playerCheckTimer -= diff; } } UpdateEscortAI(diff); }
void HandleMoveWorldportAck() { Player player = GetPlayer(); // ignore unexpected far teleports if (!player.IsBeingTeleportedFar()) { return; } bool seamlessTeleport = player.IsBeingTeleportedSeamlessly(); player.SetSemaphoreTeleportFar(false); // get the teleport destination WorldLocation loc = player.GetTeleportDest(); // possible errors in the coordinate validity check if (!GridDefines.IsValidMapCoord(loc)) { LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapRecord mapEntry = CliDB.MapStorage.LookupByKey(loc.GetMapId()); InstanceTemplate mInstance = Global.ObjectMgr.GetInstanceTemplate(loc.GetMapId()); // reset instance validity, except if going to an instance inside an instance if (!player.m_InstanceValid && mInstance == null) { player.m_InstanceValid = true; } Map oldMap = player.GetMap(); Map newMap = Global.MapMgr.CreateMap(loc.GetMapId(), player); if (player.IsInWorld) { Log.outError(LogFilter.Network, $"Player (Name {player.GetName()}) is still in world when teleported from map {oldMap.GetId()} to new map {loc.GetMapId()}"); oldMap.RemovePlayerFromMap(player, false); } // relocate the player to the teleport destination // the CannotEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if (newMap == null || newMap.CannotEnter(player) != 0) { Log.outError(LogFilter.Network, $"Map {loc.GetMapId()} could not be created for {(newMap ? newMap.GetMapName() : "Unknown")} ({player.GetGUID()}), porting player to homebind"); player.TeleportTo(player.GetHomebind()); return; } float z = loc.GetPositionZ() + player.GetHoverOffset(); player.Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation()); player.SetFallInformation(0, player.GetPositionZ()); player.ResetMap(); player.SetMap(newMap); ResumeToken resumeToken = new(); resumeToken.SequenceIndex = player.m_movementCounter; resumeToken.Reason = seamlessTeleport ? 2 : 1u; SendPacket(resumeToken); if (!seamlessTeleport) { player.SendInitialPacketsBeforeAddToMap(); } if (!player.GetMap().AddPlayerToMap(player, !seamlessTeleport)) { Log.outError(LogFilter.Network, $"WORLD: failed to teleport player {player.GetName()} ({player.GetGUID()}) to map {loc.GetMapId()} ({(newMap ? newMap.GetMapName() : "Unknown")}) because of unknown reason!"); player.ResetMap(); player.SetMap(oldMap); player.TeleportTo(player.GetHomebind()); return; } // Battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if (player.InBattleground()) { // cleanup setting if outdated if (!mapEntry.IsBattlegroundOrArena()) { // We're not in BG player.SetBattlegroundId(0, BattlegroundTypeId.None); // reset destination bg team player.SetBGTeam(0); } // join to bg case else { Battleground bg = player.GetBattleground(); if (bg) { if (player.IsInvitedForBattlegroundInstance(player.GetBattlegroundId())) { bg.AddPlayer(player); } } } } if (!seamlessTeleport) { player.SendInitialPacketsAfterAddToMap(); } else { player.UpdateVisibilityForPlayer(); Garrison garrison = player.GetGarrison(); if (garrison != null) { garrison.SendRemoteInfo(); } } // flight fast teleport case if (player.IsInFlight()) { if (!player.InBattleground()) { if (!seamlessTeleport) { // short preparations to continue flight MovementGenerator movementGenerator = player.GetMotionMaster().GetCurrentMovementGenerator(); movementGenerator.Initialize(player); } return; } // Battlegroundstate prepare, stop flight player.FinishTaxiFlight(); } if (!player.IsAlive() && player.GetTeleportOptions().HasAnyFlag(TeleportToOptions.ReviveAtTeleport)) { player.ResurrectPlayer(0.5f); } // resurrect character at enter into instance where his corpse exist after add to map if (mapEntry.IsDungeon() && !player.IsAlive()) { if (player.GetCorpseLocation().GetMapId() == mapEntry.Id) { player.ResurrectPlayer(0.5f, false); player.SpawnCorpseBones(); } } if (mInstance != null) { // check if this instance has a reset time and send it to player if so Difficulty diff = newMap.GetDifficultyID(); MapDifficultyRecord mapDiff = Global.DB2Mgr.GetMapDifficultyData(mapEntry.Id, diff); if (mapDiff != null) { if (mapDiff.GetRaidDuration() != 0) { long timeReset = Global.InstanceSaveMgr.GetResetTimeFor(mapEntry.Id, diff); if (timeReset != 0) { uint timeleft = (uint)(timeReset - GameTime.GetGameTime()); player.SendInstanceResetWarning(mapEntry.Id, diff, timeleft, true); } } } // check if instance is valid if (!player.CheckInstanceValidity(false)) { player.m_InstanceValid = false; } } // update zone immediately, otherwise leave channel will cause crash in mtmap player.GetZoneAndAreaId(out uint newzone, out uint newarea); player.UpdateZone(newzone, newarea); // honorless target if (player.pvpInfo.IsHostile) { player.CastSpell(player, 2479, true); } // in friendly area else if (player.IsPvP() && !player.HasPlayerFlag(PlayerFlags.InPVP)) { player.UpdatePvP(false, false); } // resummon pet player.ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport player.ProcessDelayedOperations(); }
bool isStatic(MovementGenerator mv) { return(false); /*(mv == &si_idleMovement);*/ }