public void SetActorToFollow(IActor actor) { _movementData = actor.GetData <MovementData>(); _transformData = actor.GetData <TransformData>(); _rotationData = actor.GetData <RotationData>(); _actorTransform = _transformData.GetTransform(); }
/// <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 OnEnable() { IMovementData movementData = GetComponent <IMovementData>(); CommandableUnit.MovementBehaviour = behaviour.StartMovementBehavior; CommandableUnit.PreferredAttackType = behaviour.StartAttackType; }
public MovementDataComponent(IMovementData data) { _data = data; _movementSpeedFactor = 1.0f; UpdateMovementSpeed(); }
/// <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); }
protected override void OnEventFired(object source, EntityCreationFinishedEventArgs args) { IMovementData movementData = MovementDataMappable.RetrieveEntity(args.EntityGuid); IMovementGenerator <IWorldObject> generator = MovementGeneratorFactory.Create(new EntityAssociatedData <IMovementData>(args.EntityGuid, movementData)); MovementGeneratorMappable.AddObject(args.EntityGuid, generator); }
protected override void OnEventFired(object source, EntityCreationStartingEventArgs args) { IMovementData movementData = MovementDataMappable.RetrieveEntity(args.EntityGuid); //We just need to make the world transform match //the initial movement data TransformMap.AddObject(args.EntityGuid, new WorldTransform(movementData.InitialPosition.x, movementData.InitialPosition.y, movementData.InitialPosition.z, movementData.Rotation)); }
protected override void OnEventFired(object source, EntityWorldObjectCreatedEventArgs args) { IMovementData movementData = MovementDataMappable.RetrieveEntity(args.EntityGuid); IMovementGenerator <IWorldObject> generator = MovementGeneratorFactory.Create(new EntityAssociatedData <IMovementData>(args.EntityGuid, movementData)); MovementGeneratorMappable.AddObject(args.EntityGuid, generator); InitializePosition(args.EntityGuid, movementData, generator, args.WorldReprensetation); }
protected override void OnEventFired(object source, EntityCreationStartingEventArgs args) { EntityPrefab prefabType = ComputePrefabType(args.EntityGuid); IMovementData movementData = MovementDataMappable.RetrieveEntity(args.EntityGuid); //load the entity's prefab from the factory GameObject prefab = PrefabFactory.Create(prefabType); GameObject entityGameObject = GameObject.Instantiate(prefab, movementData.InitialPosition, Quaternion.Euler(0, movementData.Rotation, 0)); OnEntityWorldRepresentationCreated?.Invoke(this, new EntityWorldRepresentationCreatedEventArgs(args.EntityGuid, entityGameObject)); }
/// <inheritdoc /> public DefaultEntityCreationContext(NetworkEntityGuid entityGuid, IMovementData movementData, EntityPrefab prefabType, [NotNull] IEntityDataFieldContainer entityData) { if (!Enum.IsDefined(typeof(EntityPrefab), prefabType)) { throw new InvalidEnumArgumentException(nameof(prefabType), (int)prefabType, typeof(EntityPrefab)); } EntityGuid = entityGuid ?? throw new ArgumentNullException(nameof(entityGuid)); MovementData = movementData ?? throw new ArgumentNullException(nameof(movementData)); PrefabType = prefabType; EntityData = entityData ?? throw new ArgumentNullException(nameof(entityData)); }
/// <inheritdoc /> public bool TryHandleMovement(NetworkEntityGuid entityGuid, IMovementData data) { bool result = CanHandle(data); if (result) { HandleMovement(entityGuid, data as TSpecificMovementType); } return(result); }
protected override void OnEntityCreationFinished(EntityCreationFinishedEventArgs args) { IMovementData movementData = MovementDataMappable.RetrieveEntity(args.EntityGuid); IEntityDataFieldContainer dataFieldContainer = EntityDataMappable.RetrieveEntity(args.EntityGuid); EntityCreationData data = new EntityCreationData(args.EntityGuid, movementData, EntityDataUpdateFactory.Create(new EntityFieldUpdateCreationContext(dataFieldContainer, dataFieldContainer.DataSetIndicationArray))); var senderContext = new GenericSingleTargetMessageContext <PlayerSelfSpawnEventPayload>(args.EntityGuid, new PlayerSelfSpawnEventPayload(data)); Sender.Send(senderContext); }
protected override void OnInitialize(IActor owner) { base.OnInitialize(owner); _animationData = Owner.GetData <AnimationData>(); _animator = _animationData.GetAnimator(); _movementData = Owner.GetData <MovementData>(); _bindingData = Owner.GetData <KeyBindingsData>(); _horizontalKeyAxis = _bindingData.HorizontalKeyAxis(); _verticalKeyAxis = _bindingData.VerticalKeyAxis(); }
/// <inheritdoc /> public bool TryHandleMovement(NetworkEntityGuid entityGuid, IMovementData data) { foreach (var handler in MovementHandlers) { if (handler.CanHandle(data)) { return(handler.TryHandleMovement(entityGuid, data)); } } return(false); }
/// <inheritdoc /> public async Task SaveAsync(NetworkEntityGuid guid) { //TODO: Check that the entity actually exists IMovementData movementData = MovementDataMap[guid]; //We can only handle players at the moment, not sure how NPC data would be saved. if (guid.EntityType != EntityType.Player) { return; } //TODO: Handle map ID. await ZoneToSeverClient.SaveCharacterLocation(new ZoneServerCharacterLocationSaveRequest(guid.EntityId, movementData.InitialPosition, 1)) .ConfigureAwait(false); }
public void Init(IMovementData movementData, IAttackHandler attackHandler, IDamageHanalder damageHanalder, IDefenseHandler defenseHandler) { MovementData = movementData; AttackHandler = attackHandler; AttackHandler.OnAttack += Attack; AttackHandler.PunchStateChange += OnPunchStateChange; MovementData.OnDashStateChanged += DashStateChanged; MovementData.OnJump += OnJump; MovementData.OnLand += OnLand; DamageHanalder = damageHanalder; DamageHanalder.OnDamage += OnPlayerHit; DefenseHandler = defenseHandler; DefenseHandler.DefenseStarted += OnDefense; }
protected override void OnEventFired(object source, EntityCreationStartingEventArgs args) { if (args.EntityGuid.EntityType == EntityType.Player) { //TODO: move into a factory. if (CharacterDataRepository.CharacterId == args.EntityGuid.EntityId) { //TODO: Support move than just the local player. OnEntityWorldObjectCreated?.Invoke(this, new EntityWorldObjectCreatedEventArgs(args.EntityGuid, RsUnityClient.localPlayer)); } else { Client.players[args.EntityGuid.EntityId] = new Player(); Client.players[args.EntityGuid.EntityId].visible = true; Client.players[args.EntityGuid.EntityId].lastUpdateTick = RsUnityClient.tick; Client.players[args.EntityGuid.EntityId].standAnimationId = 0x328; Client.players[args.EntityGuid.EntityId].standTurnAnimationId = 0x337; Client.players[args.EntityGuid.EntityId].walkAnimationId = 0x333; Client.players[args.EntityGuid.EntityId].turnAboutAnimationId = 0x334; Client.players[args.EntityGuid.EntityId].turnLeftAnimationId = 0x335; Client.players[args.EntityGuid.EntityId].turnRightAnimationId = 0x336; Client.players[args.EntityGuid.EntityId].runAnimationId = 0x338; Client.players[args.EntityGuid.EntityId].appearanceOffset = 336413342762192; Client.players[args.EntityGuid.EntityId].appearance = new int[12] { 0, 0, 0, 0, 275, 0, 285, 295, 259, 291, 300, 266 }; Client.players[args.EntityGuid.EntityId].name = "Unknown"; IMovementData movementData = MovementDataMappable.RetrieveEntity(args.EntityGuid); Client.players[args.EntityGuid.EntityId].setPos((int)movementData.InitialPosition.x - Client.baseX, (int)movementData.InitialPosition.z - Client.baseY); Client.localPlayers[Client.localPlayerCount++] = args.EntityGuid.EntityId; Client.playersObserved[Client.playersObservedCount++] = args.EntityGuid.EntityId; OnEntityWorldObjectCreated?.Invoke(this, new EntityWorldObjectCreatedEventArgs(args.EntityGuid, Client.players[args.EntityGuid.EntityId])); } } else { OnEntityWorldObjectCreated?.Invoke(this, new EntityWorldObjectCreatedEventArgs(args.EntityGuid, new WorldObjectStub())); } }
protected override void OnLocalPlayerSpawned(LocalPlayerSpawnedEventArgs args) { //Client region will be the x,z coordinates of the initial movement data //divided by 8 + 6. //x, z / 8 + 6 IMovementData movementData = MovementDataMappable.RetrieveEntity(args.EntityGuid); int xRegion = (int)movementData.InitialPosition.x / 8; int zRegion = (int)movementData.InitialPosition.z / 8; //current serverside z is y in RS engine. int xOffset = (int)movementData.InitialPosition.x - ((xRegion - 6) * 8); int yOffset = (int)movementData.InitialPosition.z - ((zRegion - 6) * 8); Client.InitializePlayerRegion(xRegion, zRegion); //The offset from the region should be used in setPosition //until an absolute method is available GladMMOUnityClient.localPlayer.setPos(xOffset, yOffset, true); Client.loadingMap = false; }
/// <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); }
private void InitializePosition([JetBrains.Annotations.NotNull] NetworkEntityGuid guid, [JetBrains.Annotations.NotNull] IMovementData movementData, [JetBrains.Annotations.NotNull] IMovementGenerator <IWorldObject> movementGenerator, [JetBrains.Annotations.NotNull] IWorldObject entityWorldObject) { if (guid == null) { throw new ArgumentNullException(nameof(guid)); } if (movementData == null) { throw new ArgumentNullException(nameof(movementData)); } if (movementGenerator == null) { throw new ArgumentNullException(nameof(movementGenerator)); } if (entityWorldObject == null) { throw new ArgumentNullException(nameof(entityWorldObject)); } //We need to fast forward the fake/stub WorldObject so that we can get an accurate initial position. if (movementData is PathBasedMovementData) { IWorldObject worldObjectStub = new WorldObjectStub((int)movementData.InitialPosition.x - Client.baseX, (int)movementData.InitialPosition.z - Client.baseY); //At this point, the worldObjectStub actually will have the correct initial position movementGenerator.Update(worldObjectStub, TimeService.CurrentRemoteTime); entityWorldObject.DirectSetPosition(worldObjectStub.CurrentX, worldObjectStub.CurrentY); } else { entityWorldObject.setPos((int)movementData.InitialPosition.x - Client.baseX, (int)movementData.InitialPosition.z - Client.baseY); } }
private CharacterControllerInputMovementGenerator BuildCharacterControllerMovementGenerator(NetworkEntityGuid guid, PositionChangeMovementData data, IMovementGenerator <GameObject> generator, IMovementData movementData) { //TODO: Sanity check timestamp and position. //We used to use the last generators current position //However we now use the hint position from the client. //This NEEDS to be sanity checked before used. //This semi-authorative approach is less secure but more responsive for the user. return(new CharacterControllerInputMovementGenerator(data, new Lazy <CharacterController>(() => this.CharacterControllerMappable.RetrieveEntity(guid)), data.InitialPosition)); }
/// <inheritdoc /> public bool CanHandle(IMovementData data) { return(data is TSpecificMovementType); }
public WanderMovementBehaviour(IMovementBehaviour movementBehaviour, IMovementData movementData) : base(movementBehaviour, movementData) { }
private PathBasedMovementData BuildPathData(ClientSetClickToMovePathRequestPayload payload, IMovementGenerator <GameObject> generator, IMovementData originalMovementData, NetworkEntityGuid guid) { //TODO: Sanity check timestamp and position. //So, originally we used authorative time and position but now we semi-trust the client. //We need to verify the send timestamp is not too far off and also sanity check the position too. Vector3[] path = payload.PathData.MovementPath.ToArrayTryAvoidCopy(); Vector3[] fullPath = new Vector3[path.Length + 1]; //If we haven't even started the last movement generator from the last click. if (generator.isStarted) { //Force the current position as the start point of the path. fullPath[0] = generator.CurrentPosition; } else { //We need to use the last WorldTransform because //the last movement generator has not started. WorldTransform transform = TransformMap.RetrieveEntity(guid); fullPath[0] = new Vector3(transform.PositionX, transform.PositionY, transform.PositionZ); } Array.Copy(path, 0, fullPath, 1, path.Length); return(new PathBasedMovementData(fullPath, TimeService.CurrentLocalTime)); }
/// <inheritdoc /> public AssociatedMovementData([NotNull] NetworkEntityGuid entityGuid, [NotNull] IMovementData initialMovementData) { EntityGuid = entityGuid ?? throw new ArgumentNullException(nameof(entityGuid)); InitialMovementData = initialMovementData ?? throw new ArgumentNullException(nameof(initialMovementData)); }
public AbstractMovementDecorator(IMovementBehaviour movementBehaviour, IMovementData movementData) { this.movementBehaviour = movementBehaviour; this.movementData = movementData; this.movementController = movementData.Agent.Controller; }
public PursueMovementBehaviour(IMovementBehaviour movementBehaviour, IMovementData movementData) : base(movementBehaviour, movementData) { }
private PositionChangeMovementData BuildPositionChangeMovementData(ClientMovementDataUpdateRequest payload, IMovementGenerator <GameObject> generator, IMovementData originalMovementData) { //TODO: Sanity check timestamp and position. //So, originally we used authorative time and position but now we semi-trust the client. //We need to verify the send timestamp is not too far off and also sanity check the position too. return(new PositionChangeMovementData(payload.Timestamp, payload.CurrentClientPosition, payload.MovementInput, originalMovementData.Rotation)); }
/// <inheritdoc /> public EntityCreationData([NotNull] NetworkEntityGuid entityGuid, [NotNull] IMovementData initialMovementData, [NotNull] FieldValueUpdate initialFieldValues) { EntityGuid = entityGuid ?? throw new ArgumentNullException(nameof(entityGuid)); InitialMovementData = initialMovementData ?? throw new ArgumentNullException(nameof(initialMovementData)); InitialFieldValues = initialFieldValues ?? throw new ArgumentNullException(nameof(initialFieldValues)); }
public SeekMovementBehaviour(IMovementBehaviour movementBehaviour, IMovementData movementData) : base(movementBehaviour, movementData) { }