//a method that launches the attack movement of a list of units public void LaunchAttack(List <Unit> units, FactionEntity targetEntity, Vector3 targetPosition, AttackModes attackMode, bool playerCommand) { if (units.Count == 1) //one unit only? { //use the one-unit attack movement LaunchAttack(units[0], targetEntity, targetPosition, attackMode, playerCommand); return; } if (GameManager.MultiplayerGame == false) //single player game, directly prepare the unit's attack movement { PrepareMove(units, targetPosition, targetEntity ? targetEntity.GetRadius() : 0.0f, targetEntity, InputMode.attack, playerCommand, true, attackMode, targetEntity); } else if (RTSHelper.IsLocalPlayer(units[0]) == true) //multiplayer game and this is the local player { //send input action to the input manager NetworkInput newInput = new NetworkInput() { sourceMode = (byte)InputMode.unitGroup, targetMode = (byte)InputMode.attack, targetPosition = targetPosition, value = (int)attackMode, groupSourceID = InputManager.UnitListToString(units) }; //sent input InputManager.SendInput(newInput, null, targetEntity); } }
//execute a unit group movement command public void OnUnitGroupMovementCommand(NetworkInput command) { List <Unit> unitList = StringToUnitList(command.groupSourceID); //get the units list if (unitList.Count > 0) //if there's actual units in the list { if (command.targetMode == (byte)InputMode.attack) //if the target mode is attack -> make the unit group launch an attack on the target. { FactionEntity targetEntity = spawnedObjects[command.targetID] as FactionEntity; //get the faction entity component of the target object gameMgr.MvtMgr.PrepareMove(unitList, command.targetPosition, targetEntity.GetRadius(), targetEntity, InputMode.attack, false, true, (MovementManager.AttackModes)command.value, targetEntity); } else //target movement type can be none, portal, APC, etc... { gameMgr.MvtMgr.PrepareMove(unitList, command.targetPosition, command.value, null, (InputMode)command.targetMode, true); } } }
/// <summary> /// Get the appropriate stopping distance for an attack depending on the target type. /// </summary> /// <param name="targetType">Type of the attack target.</param> /// <param name="targetRadius">Size of the target's radius.</param> /// <returns>Stopping distance for the unit's movement to launch an attack.</returns> public float GetStoppingDistance(FactionEntity target) { float stoppingDistance = 0.0f; EntityTypes targetType = target ? target.Type : EntityTypes.none; switch (targetType) { case EntityTypes.unit: stoppingDistance = unitStoppingDistance.min; break; case EntityTypes.building: stoppingDistance = buildingStoppingDistance.min; break; default: stoppingDistance = noTargetStoppingDistance.min; break; } return(stoppingDistance + (target && includeTargetRadius ? target.GetRadius() : 0.0f)); }
//a method that launches an attack movement for a single unit public void LaunchAttack(Unit unit, FactionEntity targetEntity, Vector3 targetPosition, AttackModes attackMode, bool playerCommand) { if (GameManager.MultiplayerGame == false) //single player game, directly prepare the unit's attack movement { PrepareMove(unit, targetPosition, targetEntity ? targetEntity.GetRadius() : 0.0f, targetEntity, InputMode.attack, playerCommand, true, attackMode, targetEntity); } else if (RTSHelper.IsLocalPlayer(unit) == true) //multiplayer game and this is the local player { //send input action to the input manager NetworkInput newInput = new NetworkInput() { sourceMode = (byte)InputMode.unit, targetMode = (byte)InputMode.attack, initialPosition = unit.transform.position, targetPosition = targetPosition, value = (int)attackMode, }; //sent input InputManager.SendInput(newInput, unit, targetEntity); } }
//a method that launches an attack movement for a a list of units locally public void LaunchAttackLocal(List <Unit> units, FactionEntity targetEntity, Vector3 targetPosition, AttackModes attackMode, bool playerCommand) { PrepareMove(units, targetPosition, targetEntity ? targetEntity.GetRadius() : 0.0f, targetEntity, InputMode.attack, playerCommand, true, attackMode, targetEntity); }
//execute a unit related command public void OnUnitCommand(NetworkInput command) { Unit sourceUnit = spawnedObjects[command.sourceID] as Unit; //get the source unit if (snapDistanceEnabled && sourceUnit.MovementComp.IsMoving() == false && //if the unit is not moving Vector3.Distance(sourceUnit.transform.position, command.initialPosition) > snapDistance) //snap distance if the unit's current position has moved too far from the specified initial position { sourceUnit.transform.position = command.initialPosition; //snap the unit's position } if (command.targetMode == (byte)InputMode.movement) //no target mode -> movement { gameMgr.MvtMgr.PrepareMove(sourceUnit, command.targetPosition, command.value, null, InputMode.movement, false); } else if (spawnedObjects.TryGetValue(command.targetID, out Entity target)) { switch ((InputMode)command.targetMode) { case InputMode.APC: //targetting a APC //move to target APC gameMgr.MvtMgr.PrepareMove(sourceUnit, command.targetPosition, command.value, target, InputMode.APC, false); break; case InputMode.heal: //healing the target sourceUnit.HealerComp.SetTargetLocal(target as Unit); //heal target unit break; case InputMode.convertOrder: //ordering the unit to convert sourceUnit.ConverterComp.SetTargetLocal(target as Unit); break; case InputMode.convert: //unit is getting converted sourceUnit.ConvertLocal(target as Unit, command.value); break; case InputMode.builder: //targetting a building sourceUnit.BuilderComp.SetTargetLocal(target as Building); break; case InputMode.collect: //collecting a resource sourceUnit.CollectorComp.SetTargetLocal(target as Resource); break; case InputMode.dropoff: //dropping off a resource sourceUnit.CollectorComp.SendToDropOffLocal(); break; case InputMode.portal: //moving to a portal gameMgr.MvtMgr.PrepareMove(sourceUnit, command.targetPosition, command.value, target, InputMode.portal, false); break; case InputMode.attack: //attacking the target object FactionEntity targetEntity = target as FactionEntity; //get the faction entity component of the target object gameMgr.MvtMgr.PrepareMove(sourceUnit, command.targetPosition, targetEntity.GetRadius(), targetEntity, InputMode.attack, false, true, (MovementManager.AttackModes)command.value, targetEntity); break; case InputMode.multipleAttack: //switching attack types. sourceUnit.MultipleAttackMgr.EnableAttackLocal(command.value); break; case InputMode.unitEscape: sourceUnit.EscapeComp.TriggerLocal(command.targetPosition); break; } } }