File size: 5,028 Bytes
b6a38d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
function AIBiasCombo()
local items = {}
ForEachPreset("AIArchetype", function(item)
for _, action in ipairs(item.SignatureActions) do
local id = action.BiasId
if id and id ~= "" then
table.insert_unique(items, id)
end
end
for _, behavior in ipairs(item.Behaviors) do
local id = behavior.BiasId
if id and id ~= "" then
table.insert_unique(items, id)
end
for _, action in ipairs(behavior.SignatureActions) do
local id = action.BiasId
if id and id ~= "" then
table.insert_unique(items, id)
end
end
end
end)
return items
end
DefineClass.AIBiasModification = {
__parents = { "PropertyObject" },
properties = {
{ id = "BiasId", editor = "choice", default = false, items = AIBiasCombo, },
{ id = "Effect", editor = "choice", default = "modify", items = { "modify", "disable", "priority" }, },
{ id = "Value", editor = "number", default = 0, no_edit = function(self) return self.Effect ~= "modify" end, },
{ id = "Period", editor = "number", default = 1, help = "in turns", },
{ id = "ApplyTo", editor = "choice", default = "Self", items = { "Self", "Team" }, },
},
}
function AIBiasModification:GetEditorView()
if self.BiasId and self.BiasId ~= "" then
if self.Effect == "modify" then
return string.format("%s %+d%% to %s for %d turns", self.BiasId, self.Value, self.ApplyTo, self.Period)
elseif self.Effect == "priority" then
return string.format("Make %s Priority to %s for %d turns", self.BiasId, self.ApplyTo, self.Period)
elseif self.Effect == "disable" then
return string.format("Disable %s for %s for %d turns", self.BiasId, self.ApplyTo, self.Period)
end
end
return self.class
end
DefineClass.AIBiasObj = {
__parents = { "PropertyObject" },
properties = {
{ id = "BiasId", name = "Bias Id", editor = "combo", default = false, items = AIBiasCombo },
{ id = "Weight", editor = "number", default = 100, },
{ id = "Priority", editor = "bool", default = false, },
{ id = "OnActivationBiases", name = "OnActivation Biases", editor = "nested_list", default = false, base_class = "AIBiasModification", inclusive = true, },
},
}
MapVar("g_AIBiases", {})
function AIBiasObj:OnActivate(unit)
for _, mod in ipairs(self.OnActivationBiases or empty_table) do
local id = mod.BiasId
if id then
local bias = g_AIBiases[id] or {}
g_AIBiases[id] = bias
local list
if mod.ApplyTo == "Self" then
list = bias[unit] or {}
bias[unit] = list
else
list = bias[unit.team] or {}
bias[unit.team] = list
end
list[#list + 1] = {
end_turn = g_Combat.current_turn + mod.Period,
value = mod.Value,
disable = mod.Effect == "disable",
priority = mod.Effect == "priority",
}
end
end
end
function AIUpdateBiases()
for id, item_mods in pairs(g_AIBiases) do
for obj, mods in pairs(item_mods) do
local total = 0
mods.disable = false
mods.priority = false
for i = #mods, 1, -1 do
if mods[i].end_turn < g_Combat.current_turn then
table.remove(mods, i)
else
total = total + mods[i].value
mods.disable = mods.disable or mods[i].disable
mods.priority = mods.priority or mods[i].priority
end
end
mods.total = total
end
end
end
function AIGetBias(id, unit)
local weight_mod, disable, priority = 100, false, false
if id and id ~= "" then
local mods = g_AIBiases[id] or empty_table
if mods[unit] then
weight_mod = weight_mod + mods[unit].total
disable = disable or mods[unit].disable
priority = priority or mods[unit].priority
end
if mods[unit.team] then
weight_mod = weight_mod + mods[unit.team].total
disable = disable or mods[unit.team].disable
priority = priority or mods[unit.team].priority
end
end
disable = disable or (weight_mod <= 0)
return weight_mod, disable, priority
end
function AIAltArchetypeBelowHpPercent(unit, alt_archetype, threshold)
local archetype = unit.archetype
if MulDivRound(unit.HitPoints, 100, unit.MaxHitPoints) < threshold then
archetype = alt_archetype
end
return archetype
end
function AIAltArchetypeOnAllyDeath(unit, alt_archetype, count)
local archetype = unit.archetype
local last_dead = unit:GetEffectValue("aa_num_team_dead") or 0
local dead = 0
count = count or 1
for _, other in ipairs(unit.team and unit.team.units) do
dead = dead + 1
end
if dead >= last_dead + count then
unit:SetEffectValue("aa_num_team_dead", dead)
archetype = alt_archetype
end
return archetype
end
function AIAltArchetypeOnNoEnemyDeath(unit, alt_archetype)
local archetype = unit.archetype
local last_dead = unit:GetEffectValue("aa_num_dead_enemies") or 0
local dead = 0
local unit_team = unit.team
if unit_team then
for _, team in ipairs(g_Teams) do
if unit_team:IsEnemySide(team) then
for _, other in ipairs(team.units) do
if other:IsDead() then
dead = dead + 1
end
end
end
end
end
unit:SetEffectValue("aa_num_dead_enemies", dead)
if dead == last_dead then
archetype = alt_archetype
end
return archetype
end |