diff --git a/luarules/gadgets/api_missions.lua b/luarules/gadgets/api_missions.lua index e2be576e089..d31b8588d8a 100644 --- a/luarules/gadgets/api_missions.lua +++ b/luarules/gadgets/api_missions.lua @@ -63,7 +63,9 @@ function gadget:Initialize() --local scriptPath = 'mission-api-tests/statistics_triggers_test.lua' --local scriptPath = 'mission-api-tests/resource_test.lua' --local scriptPath = 'mission-api-tests/loadout_test.lua' - local scriptPath = 'mission-api-tests/stages_and_objectives_test.lua' + --local scriptPath = 'mission-api-tests/stages_and_objectives_test.lua' + local scriptPath = 'mission-api-tests/unit_mover_test.lua' + if not scriptPath then gadgetHandler:RemoveGadget() diff --git a/luarules/mission_api/actions/move_units.lua b/luarules/mission_api/actions/move_units.lua new file mode 100644 index 00000000000..2667b559df7 --- /dev/null +++ b/luarules/mission_api/actions/move_units.lua @@ -0,0 +1,39 @@ +local ParameterTypes = GG['MissionAPI'].Modules.ParameterTypes.Types + +local function moveUnits(unitName, position, direction, randomRadius) + local tracking = GG['MissionAPI'].Modules.Tracking + if tracking.IsUnitNameUntracked(unitName) then return end + + local trackedUnitIDs = GG['MissionAPI'].trackedUnitIDs[unitName] + + for unitID in pairs(trackedUnitIDs) do + if Spring.GetUnitIsDead(unitID) == false then + if randomRadius and randomRadius > 0 then + local randomRadius = math.ceil(randomRadius) + Spring.SetUnitPosition(unitID, position.x+math.random(-randomRadius, randomRadius), position.y, position.z+math.random(-randomRadius, randomRadius)) + else + Spring.SetUnitPosition(unitID, position.x, position.y, position.z) + end + + if direction then + local testposx, _, testposz = Spring.GetUnitPosition(unitID) + if not (math.abs(direction.x-testposx) > 0.001 and math.abs(direction.z-testposz) > 0.001) then + Spring.SetUnitDirection(unitID, direction.x-testposx, direction.y, direction.z-testposz) + end + end + end + end +end + +return { + { + type = 'MoveUnits', + parameters = { + { name = 'unitName', required = true, type = ParameterTypes.UnitName }, + { name = 'position', required = true, type = ParameterTypes.Position }, + { name = 'direction', required = false, type = ParameterTypes.Position }, -- Point on the map towards which the unit rotates + { name = 'randomRadius', required = false, type = ParameterTypes.Number }, -- Spread teleported units around in radius this big. + }, + actionFunction = moveUnits, + }, +} \ No newline at end of file diff --git a/luarules/mission_api/actions/rotate_units.lua b/luarules/mission_api/actions/rotate_units.lua new file mode 100644 index 00000000000..e806dc289b4 --- /dev/null +++ b/luarules/mission_api/actions/rotate_units.lua @@ -0,0 +1,30 @@ +local ParameterTypes = GG['MissionAPI'].Modules.ParameterTypes.Types + +local function rotateUnits(unitName, direction) + local tracking = GG['MissionAPI'].Modules.Tracking + if tracking.IsUnitNameUntracked(unitName) then return end + + local trackedUnitIDs = GG['MissionAPI'].trackedUnitIDs[unitName] + + for unitID in pairs(trackedUnitIDs) do + if Spring.GetUnitIsDead(unitID) == false then + if direction then + local testposx, _, testposz = Spring.GetUnitPosition(unitID) + if not (math.abs(direction.x-testposx) >= 0.001 and math.abs(direction.z-testposz) >= 0.001) then + Spring.SetUnitDirection(unitID, direction.x-testposx, direction.y, direction.z-testposz) + end + end + end + end +end + +return { + { + type = 'RotateUnits', + parameters = { + { name = 'unitName', required = true, type = ParameterTypes.UnitName }, + { name = 'direction', required = true, type = ParameterTypes.Position }, -- Point on the map towards which the unit rotates + }, + actionFunction = rotateUnits, + }, +} \ No newline at end of file diff --git a/singleplayer/mission-api-tests/unit_mover_test.lua b/singleplayer/mission-api-tests/unit_mover_test.lua new file mode 100644 index 00000000000..654ec99e574 --- /dev/null +++ b/singleplayer/mission-api-tests/unit_mover_test.lua @@ -0,0 +1,156 @@ +local triggerTypes = GG['MissionAPI'].TriggerTypes +local actionTypes = GG['MissionAPI'].ActionDefinitions.Types + +local triggers = { + spawnTanks = { + type = triggerTypes.TimeElapsed, + parameters = { + gameFrame = 90, + }, + actions = { 'spawnTanks' }, + }, + + teleportTanksWithoutSetDirection = { + type = triggerTypes.TimeElapsed, + parameters = { + gameFrame = 150, + }, + actions = { 'teleportTanksWithoutSetDirection1' }, + }, + + teleportTanksWithSetDirection1 = { + type = triggerTypes.TimeElapsed, + parameters = { + gameFrame = 300, + }, + actions = { 'teleportTanksWithSetDirection1' }, + }, + + teleportTanksWithSetDirection2 = { + type = triggerTypes.TimeElapsed, + parameters = { + gameFrame = 450, + }, + actions = { 'teleportTanksWithSetDirection2' }, + }, + + teleportTanksWithSetDirection3 = { + type = triggerTypes.TimeElapsed, + parameters = { + gameFrame = 600, + }, + actions = { 'teleportTanksWithSetDirection3' }, + }, + + teleportTanksWithoutSetDirection2 = { + type = triggerTypes.TimeElapsed, + parameters = { + gameFrame = 750, + }, + actions = { 'teleportTanksWithoutSetDirection1' }, + }, + + rotateTanksTowardsCenterOfTheGroup = { + type = triggerTypes.TimeElapsed, + parameters = { + gameFrame = 900, + }, + actions = { 'rotateTanksTowardsCenterOfTheGroup' }, + }, +} + +local actions = { + + spawnTanks = { + type = actionTypes.SpawnUnits, + parameters = { + unitLoadout = { + { + unitDefName = 'armstump', + x = 2300, + z = 1900, + team = 0, + unitName = 'tanks', + quantity = 10 + }, + }, + }, + }, + + teleportTanksWithoutSetDirection1 = { + type = actionTypes.MoveUnits, + parameters = { + unitName = "tanks", + position = { + x = 2500, + z = 2000, + }, + randomRadius = 300, + }, + }, + + teleportTanksWithSetDirection1 = { + type = actionTypes.MoveUnits, + parameters = { + unitName = "tanks", + position = { + x = 2500, + z = 2000, + }, + direction = { + x = 3000, + z = 3000, + }, + randomRadius = 300, + }, + }, + + teleportTanksWithSetDirection2 = { + type = actionTypes.MoveUnits, + parameters = { + unitName = "tanks", + position = { + x = 2500, + z = 2000, + }, + direction = { + x = 1000, + z = 1000, + }, + randomRadius = 300, + }, + }, + + teleportTanksWithSetDirection3 = { + type = actionTypes.MoveUnits, + parameters = { + unitName = "tanks", + position = { + x = 2500, + z = 2000, + }, + direction = { + x = 2500, + z = 2000, + }, + randomRadius = 300, + }, + }, + + rotateTanksTowardsCenterOfTheGroup = { + type = actionTypes.RotateUnits, + parameters = { + unitName = "tanks", + direction = { + x = 2500, + z = 2000, + }, + }, + }, + +} + +return { + Triggers = triggers, + Actions = actions, +} \ No newline at end of file