internal void FollowPath(Vector2D weaponPos, IMovementPath path) { if (!IsWalkingEnabled) { return; } if (!currentWaypoint.HasValue || currentWaypoint.Value.DistanceTo(weaponPos) < WAYPOINT_RADIUS) { currentWaypoint = path.NextPoint; Api.Logger.Dev("Automaton: Next waypoint is " + currentWaypoint); } if (!currentWaypoint.HasValue) { Api.Logger.Error("Automaton: Failed to get next waypoint"); return; } Vector2D diff = currentWaypoint.Value - weaponPos; var moveModes = CharacterMoveModesHelper.CalculateMoveModes(diff) | CharacterMoveModes.ModifierRun; // Running will yield us more LP/minute (by miniscule amount, though) var command = new CharacterInputUpdate(moveModes, 0); // Ugh, too lazy to look for usages to understand whether `0` is "up" or "right". Probably "right", but I won't mess with trigonometry, forgive me. ((PlayerCharacter)CurrentCharacter.ProtoCharacter).ClientSetInput(command); }
private void SetInput(CharacterMoveModes moveModes, float rotationAngleRad) { this.characterInput.MoveModes = moveModes; this.characterInput.RotationAngleRad = rotationAngleRad; //// uncomment visualize rotation angle correctness with Physics Visualizer //var fromPosition = this.character.Position // + (0, this.character.ProtoCharacter.CharacterWorldWeaponOffsetRanged); //var toPosition = fromPosition + new Vector2D(30, 0).RotateRad(rotationAngleRad); //Client.Characters.CurrentPlayerCharacter.PhysicsBody.PhysicsSpace.TestLine( // fromPosition, // toPosition, // collisionGroup: null); if (!this.characterInput.HasChanged) { return; } this.characterInput.SetChanged(false); var command = new CharacterInputUpdate( this.characterInput.MoveModes, this.characterInput.RotationAngleRad); ((PlayerCharacter)this.character.ProtoCharacter) .ClientSetInput(command); }
public void ClientSetInput(CharacterInputUpdate data) { var character = Client.Characters.CurrentPlayerCharacter; if (!SharedApplyInputUpdate(data, character)) { // input not changed return; } GetClientState(Client.Characters.CurrentPlayerCharacter) .ComponentPlayerInputSender.Send(data); }
protected static bool SharedApplyInputUpdate(CharacterInputUpdate data, ICharacter character) { var privateState = GetPrivateState(character); var input = privateState.Input; input.MoveModes = data.MoveModes; input.RotationAngleRad = data.RotationAngleRad; if (input.Equals(privateState.Input)) { // input not changed return(false); } // input changed privateState.Input = input; return(true); }
internal void ServerRemote_SetInput(CharacterInputUpdate data, byte inputId) { var character = ServerRemoteContext.Character; this.CallClient(character, _ => _.ClientRemote_ServerAckInput(inputId)); var privateState = GetPrivateState(character); if (SequenceNumberHelper.GetRelativeSequenceNumberForByte(inputId, privateState.ServerLastAckClientInputId) <= 0) { //Logger.WriteDev("Server already received this or newer input: " + inputId); return; } //Logger.WriteDev("Server received new input: " + inputId + ": " + data); privateState.ServerLastAckClientInputId = inputId; SharedApplyInputUpdate(data, character); }
public void AttackTarget(IWorldObject targetObject, Vector2D intersectionPoint) { if (targetObject == null) { return; } var deltaPositionToMouseCursor = CurrentCharacter.Position + GetWeaponOffset() - intersectionPoint; var rotationAngleRad = Math.Abs(Math.PI + Math.Atan2(deltaPositionToMouseCursor.Y, deltaPositionToMouseCursor.X)); var moveModes = PlayerCharacter.GetPrivateState(CurrentCharacter).Input.MoveModes; // TODO: don't prevent moving var command = new CharacterInputUpdate(moveModes, (float)rotationAngleRad); ((PlayerCharacter)CurrentCharacter.ProtoCharacter).ClientSetInput(command); // TODO: prevent user mousemove to interrupt it SelectedItem.ProtoItem.ClientItemUseStart(SelectedItem); }