Skip to content

Commit

Permalink
Create unit_respawning.lua (#3009)
Browse files Browse the repository at this point in the history
This gadget enables unit respawning at a designated target.
This is mainly intended for Evocom.
  • Loading branch information
Xehrath committed May 18, 2024
1 parent 376b5b4 commit 2d36386
Show file tree
Hide file tree
Showing 4 changed files with 447 additions and 21 deletions.
4 changes: 2 additions & 2 deletions luarules/gadgets/sfx_notifications.lua
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ else
for ct, player in pairs (players) do
if tostring(player) then
if not unitInView then
if Spring.GetUnitRulesParam(unitID, "unit_evolved") == "true" then
if Spring.GetUnitRulesParam(unitID, "unit_evolved") then
elseif not attackerTeam and select(6, Spring.GetTeamInfo(unitTeam, false)) == myAllyTeamID and (not commanderLastDamaged[unitID] or commanderLastDamaged[unitID]+150 < Spring.GetGameFrame()) then
BroadcastEvent("NotificationEvent", "FriendlyCommanderSelfD", tostring(player))
else
Expand All @@ -274,7 +274,7 @@ else
if not unitInView then
local players = AllButAllyTeamID(GetAllyTeamID(Spring.GetUnitTeam(unitID)))
for ct, player in pairs (players) do
if tostring(player) and not Spring.GetUnitRulesParam(unitID, "unit_evolved") == "true" then
if tostring(player) and not Spring.GetUnitRulesParam(unitID, "unit_evolved") then
BroadcastEvent("NotificationEvent", "EnemyCommanderDied", tostring(player))
end
end
Expand Down
134 changes: 116 additions & 18 deletions luarules/gadgets/unit_evolution.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,13 @@ if gadgetHandler:IsSyncedCode() then
local EMPTY_TABLE = {}

local evolutionMetaList = {}
local teamPowerList = {}

local TIMER_CHECK_FREQUENCY = 30 -- gameframes
local lastTimerCheck = 0
local lastPowerCheck = 0

local TIMER_CHECK_FREQUENCY = 30 -- gameframes
local POWER_CHECK_FREQUENCY = 300 -- gameframes

include("luarules/configs/customcmds.h.lua")
--messages[1] = textColor .. Spring.I18N('ui.raptors.wave1', {waveNumber = raptorEventArgs.waveCount})
Expand All @@ -86,24 +90,28 @@ if gadgetHandler:IsSyncedCode() then


-- -- Optional:
-- evolution_announcement = "Unit Evolved", Announcement printed when the unit is evolved.
-- evolution_announcement_size = 18.5, Size of the onscreen announcement
-- evolution_announcement = "Unit Evolved", -- Announcement printed when the unit is evolved.
-- evolution_announcement_size = 18.5, -- Size of the onscreen announcement

-- -- Has a default value, as indicated, if not chosen:
-- evolution_condition = "timer" condition type for the evolution.
-- evolution_timer = 600, set the timer used for the timer condition. Given in secons from when the unit was created.
-- combatradius = 1000, Range for setting in-combat status if enemies are within range, and disabling evolution while in-combat.
-- evolution_condition = "timer", -- condition type for the evolution. "timer", "health", or "power"
-- evolution_timer = 600, -- set the timer used for the timer condition. Given in secons from when the unit was created.
-- evolution_health_threshold = 0, -- threshold for triggering the "health" evolution condition.
-- evolution_power_threshold = 600, -- threshold for triggering the "power" evolution condition.
-- evolution_power_enemy_multiplier = 1, -- Scales the power calculated based on the average enemy combined power.
-- evolution_power_multiplier = 1, -- Scales the power calculated based on your own combined power.
-- combatradius = 1000, -- Range for setting in-combat status if enemies are within range, and disabling evolution while in-combat.
-- evolution_health_transfer = "flat", -- "flat", "percentage", or "full"


-- },



function Evolve(unitID, newUnit)
local x,y,z = spGetUnitPosition(unitID)
if not z then
return
end
local health = spGetUnitHealth(unitID)
local health, maxHealth = spGetUnitHealth(unitID)
local experience = spGetUnitExperience(unitID)
local team = spGetUnitTeam(unitID)
local states = spGetUnitStates(unitID)
Expand All @@ -122,11 +130,19 @@ if gadgetHandler:IsSyncedCode() then
announcementSize = evolutionMetaList[unitID].evolution_announcement_size
end

spSetUnitRulesParam(unitID, "unit_evolved", "true", PRIVATE)
spSetUnitRulesParam(unitID, "unit_evolved", newUnitID, PRIVATE)

SendToUnsynced("unit_evolve_finished", unitID, newUnitID, announcement,announcementSize)
if evolutionMetaList[unitID].evolution_health_transfer == "full" then
elseif evolutionMetaList[unitID].evolution_health_transfer == "percentage" then
local _, newUnitMaxHealth = spGetUnitHealth(newUnitID)
local pHealth = (health/maxHealth) * newUnitMaxHealth
spSetUnitHealth(newUnitID, pHealth)
else
spSetUnitHealth(newUnitID, health)
end

spDestroyUnit(unitID, false, true)
spSetUnitHealth(newUnitID, health)
spSetUnitExperience(newUnitID, experience)
spSetUnitStockpile(newUnitID, stockpile, stockpilebuildpercent)
spSetUnitDirection(newUnitID, dx, dy, dz)
Expand All @@ -150,22 +166,36 @@ if gadgetHandler:IsSyncedCode() then

function gadget:UnitCreated(unitID, unitDefID, unitTeam)
local udcp = UnitDefs[unitDefID].customParams

if udcp.evolution_target then
evolutionMetaList[unitID] = {
evolution_target = udcp.evolution_target,
evolution_condition = udcp.evolution_condition or "timer",
evolution_timer = tonumber(udcp.evolution_timer) or 600,
evolution_power_threshold = tonumber(udcp.evolution_power_threshold) or 600,
evolution_power_enemy_multiplier = tonumber(udcp.evolution_power_enemy_multiplier) or 1,
evolution_power_multiplier = tonumber(udcp.evolution_power_multiplier) or 1,
evolution_health_threshold = tonumber(udcp.evolution_health_threshold) or 0,
evolution_disable_deathsequence = udcp.evolution_disable_deathsequence or true,
evolution_announcement = udcp.evolution_announcement,
evolution_announcement_size = tonumber(udcp.evolution_announcement_size),
combatRadius = tonumber(udcp.combatradius) or 1000,


evolution_health_transfer = udcp.evolution_health_transfer or "flat",


timeCreated = spGetGameSeconds(),
combatTimer = spGetGameSeconds(),
inCombat = false,
}
end

if UnitDefs[unitDefID].power then
if teamPowerList[unitTeam] then
teamPowerList[unitTeam] = teamPowerList[unitTeam] + UnitDefs[unitDefID].power
else
teamPowerList[unitTeam] = UnitDefs[unitDefID].power
end
end

end

--function gadget:UnitCommand(unitID, unitDefID, unitTeamID, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
Expand All @@ -174,19 +204,46 @@ if gadgetHandler:IsSyncedCode() then
-- end
--end

function gadget:UnitDestroyed(unitID)
function gadget:UnitDestroyed(unitID, unitDefID, unitTeam)
if evolutionMetaList[unitID] then
evolutionMetaList[unitID] = nil
end
end

if UnitDefs[unitDefID].power then
if teamPowerList[unitTeam] then
if teamPowerList[unitTeam] <= UnitDefs[unitDefID].power then
teamPowerList[unitTeam] = nil
else
teamPowerList[unitTeam] = teamPowerList[unitTeam] - UnitDefs[unitDefID].power
end
else
teamPowerList[unitTeam] = UnitDefs[unitDefID].power
end
end
end

function gadget:UnitPreDamaged(unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam)
if evolutionMetaList[unitID] then
if evolutionMetaList[unitID].evolution_condition == "health" then
local h, mh = spGetUnitHealth(unitID)
local currentTime = spGetGameSeconds()
if (h-damage) <= evolutionMetaList[unitID].evolution_health_threshold then
Evolve(unitID, evolutionMetaList[unitID].evolution_target)
return 0, 0
end
end
end
end


function gadget:GameFrame(f)
if f % GAME_SPEED ~= 0 then
return
end

if f % TIMER_CHECK_FREQUENCY == 0 then
--if f % TIMER_CHECK_FREQUENCY == 0 then
if ((TIMER_CHECK_FREQUENCY + lastTimerCheck) < f) then
lastTimerCheck = f
for unitID, _ in pairs(evolutionMetaList) do
local currentTime = spGetGameSeconds()
if evolutionMetaList[unitID].evolution_condition == "timer" and (currentTime-evolutionMetaList[unitID].timeCreated) >= evolutionMetaList[unitID].evolution_timer then
Expand All @@ -203,6 +260,47 @@ if gadgetHandler:IsSyncedCode() then
end
end
end

if ((POWER_CHECK_FREQUENCY + lastPowerCheck) < f) then
lastPowerCheck = f


for unitID, _ in pairs(evolutionMetaList) do
local currentTime = spGetGameSeconds()
local enemyPower = 0
local enemyCount = -1
local teamID = spGetUnitTeam(unitID)
local powerValue = 0
for team, power in pairs(teamPowerList) do
if team and teamID and power then
local teamsAllied = Spring.AreTeamsAllied(team, teamID)
if team == teamID then
powerValue = power*evolutionMetaList[unitID].evolution_power_multiplier
elseif teamsAllied == false then
enemyPower = enemyPower + power*evolutionMetaList[unitID].evolution_power_enemy_multiplier
enemyCount = enemyCount + 1
end
end
end
if enemyCount > 0 then
enemyPower = enemyPower/enemyCount
end
powerValue = powerValue + enemyPower

if evolutionMetaList[unitID].evolution_condition == "power" and powerValue > evolutionMetaList[unitID].evolution_power_threshold then
local enemyNearby = spGetUnitNearestEnemy(unitID, evolutionMetaList[unitID].combatRadius)
local inCombat = false
if enemyNearby then
inCombat = true
evolutionMetaList[unitID].combatTimer = spGetGameSeconds()
end

if not inCombat and (currentTime-evolutionMetaList[unitID].combatTimer) >= 5 then
Evolve(unitID, evolutionMetaList[unitID].evolution_target)
end
end
end
end
end


Expand Down Expand Up @@ -294,4 +392,4 @@ else
gl.DeleteList(displayList)
end

end
end

0 comments on commit 2d36386

Please sign in to comment.