Advertisement
Xetrill

STCS game_relations.script

Aug 17th, 2013
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.00 KB | None | 0 0
  1. --  отношение персонажа к актеру (или другому NPC) вычисляется по формуле:
  2. --  attitude = personal_goodwill +              -- личное отношение персонажа к актеру (если раньше не встречались, то 0)
  3. --             community_goodwill +             -- отношение группировки персонажа лично к актеру (если раньше контактов не было, то 0)
  4. --             community_to_community +         -- отношение группировки персонажа к группировке актера из [communities_relations]
  5. --           reputation_goodwill +          -- отношение репутации персонажа к репутации актера из [reputation_relations]
  6. --             rank_goodwill                    -- отношение ранга персонажа к рангу актера из [rank_relations]
  7.  
  8. --- GLOBAL --------------------------------------------------------------------
  9. default_sympathy = 0.01
  10. -- TODO check and document this tables layout.
  11. temp_goodwill_table = {}
  12.  
  13. --- LOCAL ---------------------------------------------------------------------
  14. local FRIENDS  =  1000
  15. local NEUTRALS =  0
  16. local ENEMIES  = -1000
  17.  
  18. -- 2013-08-17 13:19: ~Xetrill: Shouldn't really be here, because it's to general, and useful in
  19. -- other places as well. Could be moved to utils. I keep it in my xs_utils script.
  20. local function clamp(num, min, max)
  21.     if num < min then
  22.         return min
  23.     elseif num > max then
  24.         return max
  25.     else
  26.         return num
  27.     end
  28. end
  29.  
  30. local function invalidFactions(faction, faction_to)
  31.     return (
  32.         faction    == nil    or
  33.         faction    == 'none' or
  34.         faction_to == 'none'
  35.     )
  36. end
  37.  
  38. local relationTypeToGoodwillMap = {
  39.     enemy  = -5000,
  40.     friend =  5000
  41. }
  42. local function getGoodwillForRelationType(type)
  43.     return relationTypeToGoodwillMap[type] or 0
  44. end
  45.  
  46. --- GLOBAL --------------------------------------------------------------------
  47.  
  48. function set_factions_community(faction, faction_to, relationType)
  49.     if invalidFactions(faction, faction_to) then
  50.         return
  51.     end
  52.  
  53.     set_factions_community_num(faction, faction_to, getGoodwillForRelationType(relationType))
  54. end
  55.  
  56. function set_factions_community_num(faction, faction_to, new_community_num)
  57.     if invalidFactions(faction, faction_to) then
  58.         return
  59.     end
  60.  
  61.     relation_registry.set_community_relation(faction, faction_to, new_community_num)
  62. end
  63.  
  64. function get_factions_community(faction, faction_to)
  65.     if invalidFactions(faction, faction_to) then
  66.         return nil
  67.     end
  68.  
  69.     return relation_registry.community_relation(faction, faction_to)
  70. end
  71.  
  72. function is_factions_friends(faction, faction_to)
  73.     if invalidFactions(faction, faction_to) then
  74.         return false
  75.     end
  76.  
  77.     return relation_registry.community_relation(faction, faction_to) >= FRIENDS
  78. end
  79.  
  80. function is_factions_enemies(faction, faction_to)
  81.     if invalidFactions(faction, faction_to) then
  82.         return false
  83.     end
  84.  
  85.     return relation_registry.community_relation(faction, faction_to) <= ENEMIES
  86. end
  87.  
  88. function get_npcs_relation(npc1, npc2)
  89.     return npc1 and npc2 and npc1:relation(npc2)
  90. end
  91.  
  92. function set_npcs_relation(npc1, npc2, new_relation)
  93.     if not npc1 or not npc2 then
  94.         abort("[game_relations.set_npcs_relation]: Invalid arguments; #1 '%s', #2 '%s'.", type(npc1), type(npc2))
  95.     end
  96.  
  97.     npc1:set_goodwill(getGoodwillForRelationType(new_relation), npc2)
  98. end
  99.  
  100. function get_npc_sympathy(npc)
  101.     return npc:sympathy()
  102. end
  103.  
  104. function set_npc_sympathy(npc, new_sympathy)
  105.     if not npc then
  106.         abort("[game_relations.set_npcs_relation]: Invalid argument #1 '%s', #2 '%s'.", type(npc))
  107.     end
  108.  
  109.     npc:set_sympathy(clamp(new_sympathy, 0.0, 1.0))
  110. end
  111.  
  112. function set_squad_goodwill(squad_id, new_goodwill)
  113.     local squad = sim_board.get_sim_board().squads[squad_id]
  114.  
  115.     if not squad then
  116.         abort("[game_relations.set_squad_goodwill] Missing squad with ID '%s'.", tostring(squad_id))
  117.     end
  118.  
  119.     local goodwill = getGoodwillForRelationType(new_goodwill)
  120.     local st,  gw  = db.storage, db.goodwill
  121.     local act, obj = db.actor
  122.     -- TODO Check if squad.squad_npc is a list or map and adjust iterators accordingly.
  123.     for k, v in pairs(squad.squad_npc) do
  124.         obj = st[v] and st[v].object
  125.         if obj then
  126.             obj:set_goodwill(goodwill, act)
  127.  
  128.             if not gw.relations then
  129.                 gw.relations = {}
  130.             end
  131.             gw.relations[k] = new_goodwill
  132.         end
  133.     end
  134.  
  135.     squad.relationship = new_goodwill
  136. end
  137.  
  138. function set_squad_goodwill_to_npc(npc, squad_id, new_goodwill)
  139.     local squad = sim_board.get_sim_board().squads[squad_id]
  140.  
  141.     if not squad then
  142.         abort("[game_relations.set_squad_goodwill_to_npc] Missing squad with ID '%s'.", tostring(squad_id))
  143.     end
  144.  
  145.     local goodwill = getGoodwillForRelationType(new_goodwill)
  146.     local st       = db.storage
  147.     local obj
  148.     for k, v in pairs(squad.squad_npc) do
  149.         obj = st[v] and st[v].object
  150.         if obj then
  151.             obj:set_goodwill(goodwill, npc)
  152.         end
  153.     end
  154. end
  155.  
  156. function set_squad_community_goodwill(squad_id, community, new_goodwill)
  157.     local squad = sim_board.get_sim_board().squads[squad_id]
  158.  
  159.     if not squad then
  160.         abort("[game_relations.set_squad_community_goodwill] Missing squad with ID '%s'.", tostring(squad_id))
  161.     end
  162.  
  163.     local goodwill = getGoodwillForRelationType(new_goodwill)
  164.     local st       = db.storage
  165.     local obj
  166.     for k, v in pairs(squad.squad_npc) do
  167.         obj = st[v] and st[v].object
  168.         if obj then
  169.             obj:set_community_goodwill(community, goodwill)
  170.         end
  171.     end
  172. end
  173.  
  174. function set_level_faction_community(obj)
  175.     if not db.actor or not temp_goodwill_table.communities then
  176.         return
  177.     end
  178.  
  179.     local occ, oid = obj:character_community(), obj:id()
  180.     local act = db.actor
  181.     local aid = act:id()
  182.     -- TODO give proper names to k, v, kk and vv once it's clear what they should be named.
  183.     for k, v in pairs(temp_goodwill_table.communities) do
  184.         if occ == k then
  185.             for kk, vv in pairs(v) do
  186.                 if kk == oid then
  187.                     relation_registry.set_community_goodwill(k, aid, vv)
  188.                     obj:set_goodwill(vv, act)
  189.                     v[kk] = nil
  190.                 end
  191.             end
  192.         end
  193.     end
  194. end
  195.  
  196. function check_all_squad_members(squad_name, goodwill)
  197.     local act = db.actor
  198.     if not act then
  199.         return false
  200.     end
  201.  
  202.     local squad = sim_board.get_sim_board().squads[squad_name]
  203.     if not squad then
  204.         return false
  205.     end
  206.  
  207.     local st, obj = db.storage
  208.     for k, _ in pairs(squad.squad_npc) do
  209.         obj = st[k] and st[k].object
  210.         if obj and obj:general_goodwill(act) <= ENEMIES then
  211.             return goodwill == 'enemy'
  212.         end
  213.     end
  214.  
  215.     return goodwill == 'friend'
  216. end
  217.  
  218. function get_squad_goodwill_to_actor(squad_name)
  219.     local squad = sim_board.get_sim_board().squads[squad_name]
  220.     if not squad then
  221.         abort("[game_relations.get_squad_goodwill_to_actor] Missing squad with ID '%s'.", tostring(squad_id))
  222.     end
  223.  
  224.     if squad.relationship ~= nil then
  225.         return squad.relationship
  226.     end
  227.  
  228.     -- TODO check if 'alife():actor()' is differant somehow than 'db.actor'.
  229.     -- 2013-08-17 14:10: ~Xetrill: I don't think so, it looks like db.actor is set by the game from
  230.     -- the C++ side of things. Because there doesn't seem to be any assignment to db.actor other
  231.     -- then in db.script itself and there its's set to nil.
  232.     -- That would be easy to test, just screw up db.actor and and wait for a crash.
  233.     local goodwill = relation_registry.community_relation(squad.player_id, alife():actor():community())
  234.     if goodwill >= FRIENDS then
  235.         return 'friend'
  236.     elseif goodwill <= ENEMIES then
  237.         return 'enemy'
  238.     else
  239.         return 'neutral'
  240.     end
  241. end
  242.  
  243. function is_squad_enemy_to_actor(squad_name)
  244.     return get_squad_goodwill_to_actor(squad_name) == "enemy"
  245. end
  246.  
  247. function is_squad_friend_to_actor(squad_name)
  248.     return get_squad_goodwill_to_actor(squad_name) == "friend"
  249. end
  250.  
  251. function is_squad_neutral_to_actor(squad_name)
  252.     return get_squad_goodwill_to_actor(squad_name) == "neutral"
  253. end
  254.  
  255. function set_gulag_relation_actor(smart_name, relation)
  256.     local gulag    = xr_gulag.get_gulag_by_name(smart_name)
  257.     local goodwill = getGoodwillForRelationType(relation)
  258.  
  259.     local st,  act = db.storage, db.actor
  260.     local acc, obj = act:character_community()
  261.     -- TODO Again, check if gulag.npc_info is a list or map and adjust iterator accordingly.
  262.     for k, v in pairs(gulag.npc_info) do
  263.         obj = st[v.se_obj.id] and st[v.se_obj.id].object
  264.         if obj then
  265.             obj:set_goodwill(goodwill, act)
  266.             obj:set_community_goodwill(acc, goodwill)
  267.         end
  268.     end
  269. end
  270.  
  271. function get_gulag_relation_actor(smart_name, relation)
  272.     local act = db.actor
  273.     if not act then
  274.         return false
  275.     end
  276.  
  277.     local gulag = xr_gulag.get_gulag_by_name(smart_name)
  278.     if not gulag then
  279.         return false
  280.     end
  281.  
  282.     local goodwill, npc_count = 0, 0
  283.  
  284.     local st = db.storage
  285.     local obj, vid
  286.     for k, v in pairs(gulag.npc_info) do
  287.         vid = v.se_obj.id
  288.         obj = st[vid] and st[vid].object
  289.         if obj then
  290.             goodwill  = goodwill + obj:general_goodwill(act)
  291.             npc_count = npc_count + 1
  292.         end
  293.     end
  294.  
  295.     if npc_count == 0 then
  296.         return false
  297.     end
  298.  
  299.     goodwill = goodwill / npc_count
  300.     if relation == 'enemy' then
  301.         return goodwill <= ENEMIES
  302.     elseif relation == 'friend' then
  303.         return goodwill >= FRIENDS
  304.     else
  305.         return goodwill < FRIENDS and goodwill > ENEMIES
  306.     end
  307. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement