protected override void OnCommand(Cmd cmd) { if (cmd.Code == CmdCode.Explode) { if (cmd is MovementCmd) { MovementCmd explodeCmd = (MovementCmd)cmd; Debug.Assert(explodeCmd.HasTarget); Coordinate to = explodeCmd.Coordinates[1]; int targetPlayerIndex = explodeCmd.TargetPlayerIndex; long targetIndex = explodeCmd.TargetIndex; Explode(targetPlayerIndex, targetIndex, to); } else { TargetCmd explodeCmd = (TargetCmd)cmd; if (explodeCmd.HasTarget) { Coordinate to = m_dataController.Coordinate; int targetPlayerIndex = explodeCmd.TargetPlayerIndex; long targetIndex = explodeCmd.TargetIndex; Explode(targetPlayerIndex, targetIndex, to); } } } }
public MovementCmd(MovementCmd cmd) : base(cmd) { TargetPlayerIndex = cmd.TargetPlayerIndex; TargetIndex = cmd.TargetIndex; HasTarget = cmd.HasTarget; IsLastCmdInSequence = cmd.IsLastCmdInSequence; }
protected virtual Cmd HandleNextMoveCmd(Cmd cmd) { MovementCmd movementCmd = (MovementCmd)cmd; Coordinate to = movementCmd.Coordinates[1]; bool isLastCmdInSequence = movementCmd.IsLastCmdInSequence; const bool considerIdleStateAsValid = true; if (!m_dataController.IsValidAndEmpty(to, considerIdleStateAsValid)) { if (m_failedMoveAttempts < m_maxFailedMoveAttempts) { //Do not move if there is voxel actor or voxel bomb in one of active states. just wait a little bit return(null); } } CmdResultCode result = m_dataController.Move(to, isLastCmdInSequence, EatOrDestroyCallback); if (result != CmdResultCode.Success) { RaiseCmdFailed(cmd, result); } return(cmd); }
protected virtual void PopulateCommandsQueue(long unitIndex, Coordinate[] path, bool isAutomatedAction, int moveCode) { int dir = m_dataController.ControlledData.Dir; for (int i = 0; i < path.Length - 1; ++i) { Coordinate from = path[i]; Coordinate to = path[i + 1]; int rotateLeft = VoxelData.ShouldRotateLeft(dir, from, to); int rotateRight = VoxelData.ShouldRotateRight(dir, from, to); if (rotateLeft > 0) { for (int r = 0; r < rotateLeft; ++r) { dir = VoxelData.RotateLeft(dir); Cmd rotateCmd = new Cmd(CmdCode.RotateLeft, unitIndex); rotateCmd.Duration = m_dataController.Abilities.RotationDuration; m_commandsQueue.Enqueue(rotateCmd); } } else if (rotateRight > 0) { for (int r = 0; r < rotateRight; ++r) { dir = VoxelData.RotateRight(dir); Cmd rotateCmd = new Cmd(CmdCode.RotateRight, unitIndex); rotateCmd.Duration = m_dataController.Abilities.RotationDuration; m_commandsQueue.Enqueue(rotateCmd); } } MovementCmd moveCmd = new MovementCmd { Code = moveCode, Duration = m_dataController.Abilities.MovementDuration, Coordinates = new[] { from, to }, UnitIndex = unitIndex }; if (i == path.Length - 2) { moveCmd.IsLastCmdInSequence = true && !isAutomatedAction; } m_commandsQueue.Enqueue(moveCmd); } }
protected override void OnCompleted() { MovementCmd cmd = (MovementCmd)m_taskInfo.Cmd; if (cmd.Coordinates[cmd.Coordinates.Length - 1].MapPos == m_unit.DataController.Coordinate.MapPos) { m_taskInfo.State = TaskState.Completed; } else { m_taskInfo.StatusCode = TaskInfo.TaskFailed; m_taskInfo.State = TaskState.Completed; } }
protected virtual void OnMove(Cmd cmd) { MovementCmd coordinateCmd = (MovementCmd)cmd; Coordinate to = coordinateCmd.Coordinates[1]; bool isLastCmd = coordinateCmd.IsLastCmdInSequence; CmdResultCode noFail = m_dataController.Move(to, isLastCmd, EatOrDestroyCallback, CollapseCallback, ExpandCallback, ExplodeCallback); if (noFail != CmdResultCode.Success) { throw new InvalidOperationException(); } VoxelData voxelData = m_dataController.ControlledData; MapPos mapPos = m_dataController.Coordinate.MapPos; int weight = m_dataController.Coordinate.Weight; Debug.Assert(weight == m_dataController.ControlledData.Weight); bool wasVisible = m_controlledVoxel != null; AcquireReleaseVisibility(voxelData, mapPos, weight); bool isVisible = m_controlledVoxel != null; if (wasVisible && isVisible) { m_controlledVoxel.Move(voxelData.Altitude, m_currentTick, m_currentCmdDuration); } else { m_eatCommands.Clear(); //clear needed because voxel already reflected current Health value during AcquireReleaseVisibility method call //no execution of eat commands required in this case CollapseEatExpandClear(m_currentTick); Explode(0); } }
protected void OnMoveSearchPath(Cmd cmd) { //m_ticksBeforeNextCommand = 0;// <-- this will enable immediate commands MovementCmd coordinateCmd = (MovementCmd)cmd; Coordinate[] cmdCoordinates = coordinateCmd.Coordinates; if (cmdCoordinates == null || cmdCoordinates.Length != 1) { RaiseCmdFailed(cmd, CmdResultCode.Fail_InvalidArguments); return; } cmdCoordinates = ToWaypoints(cmdCoordinates); State = VoxelDataState.SearchingPath; m_pathFinder.Find(Id, -1, m_dataController.Clone(), cmdCoordinates, (unitIndex, path) => { State = VoxelDataState.Moving; PopulateCommandsQueue(unitIndex, path, false, CmdCode.Move); }, null); }
private void CreateMovementCmd(bool serverSide, Action <List <Cmd> > callback) { Guid playerId = m_gameState.GetLocalPlayerId(m_localPlayerIndex); int playerIndex = m_gameState.GetPlayerIndex(playerId); long[] selectedUnitIds = m_unitSelection.GetSelection(playerIndex, playerIndex); if (selectedUnitIds.Length > 0) { List <Cmd> commandsToSubmit = new List <Cmd>(); for (int i = 0; i < selectedUnitIds.Length; ++i) { long unitIndex = selectedUnitIds[i]; IVoxelDataController dataController = m_gameState.GetVoxelDataController(playerIndex, unitIndex); MapCell cell = m_map.GetCell(m_cameraController.MapCursor, m_cameraController.Weight, null); int deltaWeight = dataController.ControlledData.Weight - m_cameraController.Weight; while (deltaWeight > 0) { cell = cell.Parent; deltaWeight--; } VoxelData selectedTarget = null; //MapCell selectedTargetCell = null; for (int p = 0; p < m_gameState.PlayersCount; ++p) { long[] targetSelection = m_targetSelection.GetSelection(playerIndex, p); if (targetSelection.Length > 0) { MatchAssetCli asset = m_gameState.GetAsset(p, targetSelection[0]); if (asset != null) { selectedTarget = asset.VoxelData; // selectedTargetCell = asset.Cell; } else { IVoxelDataController dc = m_gameState.GetVoxelDataController(p, targetSelection[0]); selectedTarget = dc.ControlledData; // selectedTargetCell = m_map.GetCell(dc.Coordinate.MapPos, dc.Coordinate.Weight, null); } } } int dataType = dataController.ControlledData.Type; int dataWeight = dataController.ControlledData.Weight; VoxelData beneath = null; if (cell != null) { if (selectedTarget == null) { VoxelData defaultTarget; beneath = cell.GetDefaultTargetFor(dataType, dataWeight, playerIndex, false, out defaultTarget); } else { beneath = cell.GetPreviousFor(selectedTarget, dataType, dataWeight, playerIndex); } } VoxelData closestBeneath = beneath; float minDistance = float.MaxValue; if (closestBeneath == null && cell != null) { MapPos pos = cell.GetPosition(); for (int r = -1; r <= 1; r++) { for (int c = -1; c <= 1; c++) { MapCell neighbourCell = m_map.GetCell(new MapPos(pos.Row + r, pos.Col + c), dataController.ControlledData.Weight, null); if (neighbourCell != null) { VoxelData defaultTarget; VoxelData data = neighbourCell.GetDefaultTargetFor(dataType, dataWeight, playerIndex, false, out defaultTarget); Vector3 worldPoint = m_map.GetWorldPosition(new MapPos(pos.Row + r, pos.Col + c), dataWeight); if (data != null) { worldPoint.y = (data.Altitude + data.Height) * GameConstants.UnitSize; } Vector2 screenPoint = m_cameraController.WorldToScreenPoint(worldPoint); if (m_cameraController.InScreenBounds(screenPoint)) { float distance = (screenPoint - m_cameraController.VirtualMousePosition).magnitude; if (data != null && distance < minDistance) { minDistance = distance; closestBeneath = data; cell = neighbourCell; } } } } } } beneath = closestBeneath; if (beneath != null) { int weight = dataController.ControlledData.Weight; // Vector3 hitPoint = beneath.Weight <= weight ? m_map.GetWorldPosition(m_cameraController.MapCursor, m_cameraController.Weight) : m_cameraController.Cursor; //MapPos mapPos = m_map.GetMapPosition(hitPoint, weight); MapPos mapPos = cell.GetPosition(); int altitude = beneath.Altitude + beneath.Height; if (serverSide) { MovementCmd movementCmd = new MovementCmd(); if (selectedTarget != null) { movementCmd.HasTarget = true; movementCmd.TargetIndex = selectedTarget.UnitOrAssetIndex; movementCmd.TargetPlayerIndex = selectedTarget.Owner; } Coordinate targetCoordinate = new Coordinate(mapPos, weight, altitude); movementCmd.Code = CmdCode.Move; movementCmd.Coordinates = new[] { targetCoordinate }; movementCmd.UnitIndex = unitIndex; commandsToSubmit.Add(movementCmd); } else { Coordinate targetCoordinate = new Coordinate(mapPos, weight, altitude); m_engine.GetPathFinder(m_gameState.LocalToPlayerIndex(LocalPlayerIndex)).Find(unitIndex, -1, dataController.Clone(), new[] { dataController.Coordinate, targetCoordinate }, (unitId, path) => { MovementCmd movementCmd = new MovementCmd(); movementCmd.Code = CmdCode.Move; movementCmd.Coordinates = path; movementCmd.UnitIndex = unitIndex; commandsToSubmit.Add(movementCmd); callback(commandsToSubmit); }, null); } } } if (serverSide) { callback(commandsToSubmit); } } callback(null); }
private void Update() { m_playersBot.Update(Time.realtimeSinceStartup); if (m_gameState.IsActionsMenuOpened(LocalPlayerIndex)) { return; } if (m_gameState.IsContextActionInProgress(LocalPlayerIndex)) { return; } if (m_gameState.IsMenuOpened(LocalPlayerIndex)) { return; } if (m_gameState.IsPaused || m_gameState.IsPauseStateChanging) { return; } if (m_inputManager.GetButtonDown(InputAction.A, LocalPlayerIndex) || m_inputManager.GetButtonDown(InputAction.RMB, LocalPlayerIndex)) { m_wasAButtonDown = true; CreateMovementCmd(false, cmd => { if (cmd != null && cmd.Count > 0) { MovementCmd movementCmd = (MovementCmd)cmd[0]; if (!m_inputManager.IsKeyboardAndMouse(LocalPlayerIndex)) { m_cameraController.SetVirtualMousePosition(movementCmd.Coordinates.Last(), true, true); } } }); } else if (m_inputManager.GetButtonUp(InputAction.A, LocalPlayerIndex) || m_inputManager.GetButtonUp(InputAction.RMB, LocalPlayerIndex)) { if (m_wasAButtonDown) { CreateMovementCmd(false, cmd => { if (cmd != null && cmd.Count > 0) { MovementCmd movementCmd = (MovementCmd)cmd[0]; if (!m_inputManager.IsKeyboardAndMouse(LocalPlayerIndex)) { m_cameraController.SetVirtualMousePosition(movementCmd.Coordinates.Last(), true, true); } SubmitToEngine(m_gameState.LocalToPlayerIndex(LocalPlayerIndex), cmd); } }); m_wasAButtonDown = false; } } else if (m_inputManager.GetButtonDown(InputAction.B, LocalPlayerIndex, false, false)) { OnCancel(); } else if (m_inputManager.GetButtonDown(InputAction.Y, LocalPlayerIndex, false, false)) { m_commandsPanel.IsOpen = true; } }