Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2014
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function resolvers.calc.talented_ai_tactic(t, e)
  2. local old_on_added_to_level = e.on_added_to_level
  3. e.on_added_to_level = function(self, level, x, y)
  4. if old_on_added_to_level then old_on_added_to_level(self, level, x, y) end
  5. print(" # talented_ai_tactic resolver function for", e.name, "level=", e.level)
  6. local tactic_total = t[2] or t.tactic_total or 10 --want tactic weights to total 10
  7. local weight_power = t[3] or t.weight_power or 0.5 --smooth out tactical weights
  8. local tacs_offense = {attack=1, attackarea=1}
  9. local tacs_close = {closein=1, go_melee=1}
  10. local tacs_defense = {escape=1, defend=1, heal=1, protect=1, disable = 1}
  11. local tac_types = {type="melee",type = "ranged", type="tank", type="survivor"}
  12. local tactic, tactical = {}, {total = 0}
  13. local count = {talents = 0, atk_count = 0, atk_value = 0, total_range = 0,
  14. atk_melee = 0, melee_value = 0, range_value = 0, atk_range = 0,
  15. escape = 0, close = 0, def_count = 0, def_value = 0, disable=0}
  16. local do_count, val
  17. local tac_count = #table.keys(tacs_offense) + #table.keys(tacs_close) + #table.keys(tacs_defense)
  18. -- go through all talents, adding up all the tactical weights from the tactical tables weighted by talent level
  19. local tal
  20. local get_weight = function(wt)
  21. local val = 0
  22. if type(wt) == "function" then
  23. wt = wt(e, tal, e) -- try to target self for effectiveness
  24. end
  25. if type(wt) == "number" then return wt
  26. elseif type(wt) == "table" then
  27. for _, n in pairs(wt) do
  28. val = math.max(val, get_weight(n))
  29. end
  30. if val == 0 then val = 2 end
  31. end
  32. return tonumber(val) or 0
  33. end
  34.  
  35. for tid, tl in pairs(e.talents) do
  36. local get_weight2 = function(wt)
  37. local val = 0
  38. if type(wt) == "function" then
  39. wt = wt(e, tal, e) -- try to target self for effectiveness
  40. end
  41. if type(wt) == "number" then return wt
  42. elseif type(wt) == "table" then
  43. for _, n in pairs(wt) do
  44. val = math.max(val, get_weight(n))
  45. end
  46. if val == 0 then val = 2 end
  47. end
  48. return tonumber(val) or 0
  49. end
  50. tal = e:getTalentFromId(tid)
  51. local range = e:getTalentRange(tal)
  52. if range > 0 then range = range + e:getTalentRadius(tal)*2/3 end
  53. if tal and tal.tactical then
  54. print(" # tactical table for talent", tal.name, "range", range)
  55. table.print(tal.tactical)
  56. do_count = false
  57. for tt, wt in pairs(tal.tactical) do
  58. val = get_weight(wt, e)
  59. --[[
  60. val = 0
  61. if type(wt) == "function" then
  62. val = wt(e, tal, e) -- try to target self for effectiveness
  63. end
  64. if type(wt) == "number" then val = wt
  65. elseif type(wt) == "table" then
  66. for _, n in pairs(wt) do
  67. if type(n) == "number" then val = math.max(val, n) end
  68. end
  69. if val == 0 then val = 2 end
  70. end
  71. val = tonumber(val) or 0
  72. --]]
  73. print(" # ", tt, "wt=", val)
  74. tactical[tt] = (tactical[tt] or 0) + val -- sum up all the input weights
  75. if tacs_offense[tt] then
  76. do_count = true
  77. count.atk_count = count.atk_count + 1
  78. val = val * tacs_offense[tt]
  79. count.atk_value = count.atk_value + val
  80. count.total_range = count.total_range + range
  81. if range >= 2 then
  82. count.atk_range = count.atk_range + 1
  83. count.range_value = count.range_value + val
  84. else
  85. count.atk_melee = count.atk_melee + 1
  86. count.melee_value = count.melee_value + val
  87. end
  88. end
  89. if tacs_defense[tt] then
  90. do_count = true
  91. count.def_count = count.def_count + 1
  92. count.def_value = count.def_value + tacs_defense[tt] * val
  93. if tt == "escape" then count.escape = count.escape + 1 end
  94. end
  95. if tacs_close[tt] then
  96. do_count = true
  97. count.close = count.close + 1
  98. end
  99. if do_count then
  100. count.talents = count.talents + 1
  101. tactical.total = tactical.total + val
  102. tactic[tt] = (tactic[tt] or 0) + val -- sum up only relevant weights
  103. end
  104. end
  105. end
  106. end
  107. -- collapse tactics ATTACK, ATTACKAREA by range
  108. -- compute tactical weights{disable=3, escape=0, closein=2, defend=2, protect=2, heal=3, go_melee=1} based on weights
  109. local ttype = "test"
  110. -- normalize weights
  111. count.avg_attack_range = count.total_range/count.atk_count
  112. local norm_total = 0
  113. for tt, wt in pairs(tactic) do
  114. -- tactic[tt] = (tactic[tt]/count.talents)
  115. -- tactic[tt] = (tactic[tt]/tactical.total) - count.talents
  116. local ave_weight = (tactic[tt]+count.talents)/count.talents
  117. local ave_xweight = ave_weight^weight_power - 1
  118. if ave_xweight > 1/tac_count then
  119. tactic[tt] = ave_weight
  120. norm_total = norm_total + ave_weight
  121. else
  122. tactic[tt] = nil -- defaults to a weight of 1 in the tactical ai
  123. end
  124. end
  125. for tt, _ in pairs(tactic) do
  126. tactic[tt] = tactic[tt]*tactic_total/norm_total
  127. if tactic[tt] < 1 then tactic[tt] = nil end -- defaults to a weight of 1 in the tactical ai
  128. end
  129.  
  130. -- Minimum range?
  131. if count.atk_range + count.escape > count.atk_melee + count.close and count.range_value /(count.melee_value + 1) > 1.5 then
  132. tactic.safe_range = math.max(2, math.ceil(count.avg_attack_range/2)) --only for ranged/survivor
  133. end
  134.  
  135. -- compute "tank"/"survivor" based on "escape","defend", and "heal" weights
  136. tactic.tactical_sum=tactical tactic.count = count
  137. tactic.type = ttype
  138. tactic.tac_count = tac_count
  139. tactic.level = e.level
  140. for tac, wt in pairs(tactic) do print(" ##", tac, wt) end
  141. self.ai_tactic_resolved = true
  142. self.ai_tactic = tactic
  143. -- self.on_added_to_level = nil
  144. return tactic
  145. end
  146. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement