Guest User

Control.lua on load fix for RPG_ITEMS

a guest
Jan 26th, 2026
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 33.43 KB | Fixit | 0 0
  1. if script.active_mods["gvv"] then require("__gvv__.gvv")() end
  2.  
  3. require("ITEMS")
  4. require("rpg_framework")
  5.  
  6.  
  7. local random = math.random
  8. local floor = math.floor
  9. local max = math.max
  10. local min = math.min
  11. local RED_COLOR = {r=1,g=0,b=0}
  12.  
  13.  
  14. remote.add_interface("rpg-items", {
  15.     get = function(field) return storage[field] end,
  16.     set = function(field, value)
  17.         storage[field] = value
  18.     end,
  19.     add_gold = function(force, value)
  20.         local force_data = storage.forces[force.name]
  21.         if not force_data then return false end
  22.         force_data.money = max(0, force_data.money + value)
  23.         return true
  24.     end,
  25.     get_gold = function(force)
  26.         local force_data = storage.forces[force.name]
  27.         if not force_data then return false end
  28.         return force_data.money
  29.     end,
  30.     set_item = function(item, tbl) -- TODO: change
  31.         storage.items[item] = tbl
  32.         if storage.items[item].func then
  33.             storage.items[item].func = load(storage.items[item].func)
  34.             if not type(storage.items[item].func) == "function" then
  35.                 error("couldn't load function")
  36.             end
  37.         end
  38.     end
  39. })
  40.  
  41.  
  42. local function refresh_forces()
  43.     -- Init force data
  44.     for _, force in pairs(game.forces) do
  45.         local force_name = force.name
  46.         if force.players then
  47.             if not storage.forces[force_name] then
  48.                 storage.forces[force_name] = {
  49.                     players = {}, color = force, research = {}, money = 16000,
  50.                     bonuses = {
  51.                         income = 1, crit = 0, critdamage = 0, armor = 0, thorns = 0, regen = 1.5,
  52.                         chardamage = 0, chardamage_mult = 1, repair = 0, pctregen = 0, lifesteal = 0,
  53.                         pctlifesteal = 0, energy = 0, revive = 0, stun = 0, momentum = 0, immolation = 0
  54.                     },
  55.                     bonus_talents = 0, giveitem={}, modifiers = {},talent_modifiers = {}, items = {}, item_cooldowns = {}, bonus_slots = 0
  56.                 }
  57.             end
  58.         end
  59.  
  60.         if storage.forces[force_name] then
  61.             storage.forces[force_name].players = force.players
  62.             for _, player in pairs(force.players) do
  63.                 create_equipment_gui(player)
  64.                 local talents_data = storage.talents[force_name]
  65.                 if not talents_data or not talents_data.ready then
  66.                     talents_gui(player)
  67.                 end
  68.             end
  69.         end
  70.     end
  71.  
  72.     -- Remove invalid force data
  73.     for force_name in pairs(storage.forces) do
  74.         local force = game.forces[force_name]
  75.         if not (force and force.valid) then
  76.             storage.forces[force_name] = nil
  77.         end
  78.     end
  79. end
  80.  
  81. local function initialize_global_data()
  82.     storage.indestructible_characters = storage.indestructible_characters or {}
  83.     make_items()
  84.     storage.all_talents = {
  85.     r={
  86.         ["t1"] = {type = "force", modifier = "ammo_damage_modifier", value = 0.02},
  87.         ["t2"] = {type = "force", modifier = "ammo_damage_modifier", value = 0.0002, periodical = 0},
  88.         ["t3"] = {type = "force", modifier = "gun_speed_modifier", value = 0.03},
  89.         ["t4"] = {type = "other", modifier = "crit", value = 0.005},
  90.         ["t5"] = {type = "other", modifier = "critdamage", value = 0.015},
  91.         --["t6"] = {type = "other", modifier = "chardamage", value = 2},
  92.         --["t7"] = {type = "force", modifier = "turret_attack_modifier", value = 0.02},
  93.         ["t8"] = {type = "other", modifier = "thorns", value = 0.5},
  94.         ["t9"] = {type = "other", modifier = "thorns", value = 0.005, periodical = 0},
  95.         ["t27"] = {type = "other", modifier = "lifesteal", value = 0.05},
  96.     },
  97.     g={
  98.         ["t10"] = {type = "other", modifier = "income", value = 0.05},
  99.         ["t11"] = {type = "force", modifier = "character_health_bonus", value = 10},
  100.         ["t12"] = {type = "force", modifier = "character_health_bonus", value = 0.1, periodical = 0},
  101.         ["t13"] = {type = "other", modifier = "regen", value = 0.3},
  102.         ["t14"] = {type = "other", modifier = "regen", value = 0.003, periodical = 0},
  103.         ["t15"] = {type = "other", modifier = "armor", value = 1},
  104.         ["t16"] = {type = "other", modifier = "armor", value = 0.01, periodical = 0},
  105.         ["t17"] = {type = "force", modifier = "character_running_speed_modifier", value = 0.02},
  106.     },
  107.     b={
  108.         ["t18"] = {type = "force", modifier = "manual_mining_speed_modifier", value = 0.1},
  109.         ["t19"] = {type = "force", modifier = "manual_crafting_speed_modifier", value = 0.05},
  110.         ["t20"] = {type = "force", modifier = "character_inventory_slots_bonus", value = 1},
  111.         ["t26"] = {type = "force", modifier = "character_reach_distance_bonus", value = 1},
  112.     },
  113. }
  114.     if script.active_mods["m-spell-pack"] then
  115.         storage.use_spellpack = true
  116.         --storage.all_talents.b["t21"] = {type = "other", modifier = "magic_resistance", value = 2}
  117.         --storage.all_talents.b["t22"] = {type = "other", modifier = "magic_resistance", value = 0.06, periodical = 0}
  118.         storage.all_talents.b["t23"] = {type = "spellpack", modifier = "max_mana", value = 2}
  119.         storage.all_talents.b["t24"] = {type = "spellpack", modifier = "max_mana", value = 0.02, periodical = 0}
  120.         storage.all_talents.b["t25"] = {type = "spellpack", modifier = "mana_reg", value = 0.05}
  121.     end
  122.     storage.talent_localizations = {
  123.         ["t1"]="+2% Damage",
  124.         ["t2"]="+0.2% Damage/hour",
  125.         ["t3"]="+3% Attackspeed",
  126.         ["t4"]="+0.5% Crit",
  127.         ["t5"]="+1.5% Critdamage",
  128.         --["t6"]="+2 Melee Damage",
  129.         --["t7"]="+2% Turret Damage",
  130.         ["t8"]="+0.5 Thorns Damage",
  131.         ["t9"]="+0.05 Thorns Damage/hour",
  132.         ["t10"]="+0.05 Gold/s",
  133.         ["t11"]="+10 Health",
  134.         ["t12"]="+1 Health/hour",
  135.         ["t13"]="+0.3 HP/s",
  136.         ["t14"]="+0.03 HP/s/hour",
  137.         ["t15"]="+1 Armor",
  138.         ["t16"]="+0.1 Armor/hour",
  139.         ["t17"]="+2% Running speed",
  140.         ["t18"]="+10% Mining Speed",
  141.         ["t19"]="+5% Crafting Speed",
  142.         ["t20"]="+1 Inventory Slot",
  143.         --["t21"]="+2 Magic resistance",
  144.         --["t22"]="+0.02 Magic resistance/hour",
  145.         ["t23"]="+2 Mana",
  146.         ["t24"]="+0.2 Mana/hour",
  147.         ["t25"]="+0.05 Manareg",
  148.         ["t26"]="+1 Reach Distance",
  149.         ["t27"]="+0.05% Lifesteal",
  150.     }
  151. end
  152.  
  153. script.on_init( function()
  154.     initialize_global_data()
  155.    
  156.     storage.initialized = true
  157.     storage.giveitem_cache = {}
  158.     storage.forces = {}
  159.     storage.repairing = {}
  160.     storage.momentum = {}
  161.     storage.immolation = {}
  162.     --storage.units = {}
  163.     --storage.lobbys = {}
  164.     --storage.eq_gui_clicks = {}
  165.     storage.talents = {}
  166.     refresh_forces()
  167.     -- storage.version = 3
  168. end)
  169.  
  170. script.on_load(initialize_global_data)
  171.  
  172. script.on_event(defines.events.on_game_created_from_scenario, function()
  173.     if remote.interfaces["rpgitems_dont_make_market"] then return end
  174.  
  175.     local surface = game.surfaces[1]
  176.     local pos = surface.find_non_colliding_position("rocket-silo", {x=0,y=0}, 50, 0.5, true)
  177.     if pos then
  178.         local market = surface.create_entity{name = "rpgitems-market", position = pos, force = "player"}
  179.         market.minable = false
  180.     end
  181. end)
  182.  
  183. script.on_configuration_changed(function()
  184.     initialize_global_data()
  185.    
  186.     -- if not storage.version then
  187.         -- storage.version = 1
  188.         -- for _, data in pairs(storage.forces) do
  189.         --  if data.bonuses.revive > 0 then
  190.         --      data.bonuses.revive = 5
  191.         --  end
  192.         -- end
  193.         -- if storage.items["rpgitems_crusader"].effects[6].modifier == "revive" then
  194.         --  storage.items["rpgitems_crusader"].effects[6].value = 5
  195.         -- else
  196.         --  game.print("Error migrating the crusader buff, please report this issue to the author")
  197.         -- end
  198.         -- if storage.items["rpgitems_crusader_spepa"].effects[7].modifier == "revive" then
  199.         --  storage.items["rpgitems_crusader_spepa"].effects[7].value = 5
  200.         -- else
  201.         --  game.print("Error migrating the crusader buff, please report this issue to the author")
  202.         -- end
  203.     -- end
  204.     -- if storage.version < 2 then
  205.     --  storage.version = 2
  206.     --  for _, data in pairs(storage.forces) do
  207.     --      data.bonus_talents = 0
  208.     --  end
  209.     --  if storage.items["rpgitems_amnesia_book"] then
  210.     --      storage.items["rpgitems_amnesia_book"].description = "Allows you to reset your talents\nGrants +4 talent points (RGBW)\nChanged per hour bonuses will start from 0!"
  211.     --      storage.items["rpgitems_amnesia_book"].price = 35000
  212.     --  end
  213.     -- end
  214.     -- if storage.version <3 then
  215.     --  storage.version = 3
  216.     --  if remote.interfaces["spell-pack"] then
  217.     --      for force_name, force_data in pairs(storage.forces) do
  218.     --          for mod_id, modifier in pairs(force_data.modifiers) do
  219.     --              if modifier.type == "spellpack" then
  220.     --                  local mult = 1
  221.     --                  if modifier.periodical then
  222.     --                      mult = modifier.periodical
  223.     --                  end
  224.     --                  local players =remote.call("spell-pack","get","players")
  225.     --                  for _, player in pairs(storage.forces[force_name].players) do
  226.     --                      local new_mod = players[player.index][modifier.modifier]- modifier.value*mult
  227.     --                      players[player.index][modifier.modifier] = new_mod
  228.     --                  end
  229.     --                  remote.call("spell-pack","set","players",players)
  230.     --
  231.     --                  if tonumber(script.active_mods["m-spell-pack"]:sub(-2)) >= 18 then
  232.     --                      remote.call("spell-pack", "modforce", game.forces[force_name],modifier.modifier, modifier.value*mult)
  233.     --                  else
  234.     --                      force_data.modifiers[mod_id] = nil
  235.     --                      game.print("Please update Spell-Pack")
  236.     --                  end
  237.     --              end
  238.     --          end
  239.     --          for mod_id, modifier in pairs(force_data.talent_modifiers) do
  240.     --              if modifier.type == "spellpack" then
  241.     --                  local mult = 1
  242.     --                  if modifier.periodical then
  243.     --                      mult = modifier.periodical
  244.     --                  end
  245.     --                  local players =remote.call("spell-pack","get","players")
  246.     --                  for _, player in pairs(storage.forces[force_name].players) do
  247.     --                      local new_mod = players[player.index][modifier.modifier]- modifier.value*mult
  248.     --                      players[player.index][modifier.modifier] = new_mod
  249.     --                  end
  250.     --                  remote.call("spell-pack","set","players",players)
  251.     --
  252.     --                  if tonumber(script.active_mods["m-spell-pack"]:sub(-2)) >= 18 then
  253.     --                      remote.call("spell-pack", "modforce", game.forces[force_name],modifier.modifier, modifier.value*mult)
  254.     --                  else
  255.     --                      force_data.modifiers[mod_id] = nil
  256.     --                      game.print("Please update Spell-Pack")
  257.     --                  end
  258.     --              end
  259.     --          end
  260.     --      end
  261.     --  end
  262.         -- for _, data in pairs(storage.items) do
  263.         --  if data.requires == "m-spell-pack" or data.conflicts == "m-spell-pack" then
  264.         --      data.andversion = 18
  265.         --  end
  266.         -- end
  267.     -- end
  268.     if script.active_mods["m-spell-pack"] and tonumber(script.active_mods["m-spell-pack"]:sub(-2)) >= 18 and not storage.use_spellpack then
  269.         storage.use_spellpack = true
  270.         storage.all_talents.b["t23"] = {type = "spellpack", modifier = "max_mana", value = 2}
  271.         storage.all_talents.b["t24"] = {type = "spellpack", modifier = "max_mana", value = 0.02, periodical = 0}
  272.         storage.all_talents.b["t25"] = {type = "spellpack", modifier = "mana_reg", value = 0.05}
  273.         for i, data in pairs(storage.forces) do
  274.             for id, item in pairs(data.items) do
  275.                 if storage.items[item.item].conflicts and storage.items[item.item].conflicts == "m-spell-pack" then
  276.                     data.money = data.money + get_sell_price(item.item)*item.count
  277.                     data.items[id] = nil
  278.                 end
  279.             end
  280.             update_items(game.forces[i])
  281.         end
  282.         game.print("Added spellpack talents and items :)")
  283.     end
  284.     if (script.active_mods["m-spell-pack"] and tonumber(script.active_mods["m-spell-pack"]:sub(-2)) < 18) and storage.use_spellpack then
  285.         storage.use_spellpack = false
  286.         storage.all_talents.b["t23"] = nil
  287.         storage.all_talents.b["t24"] = nil
  288.         storage.all_talents.b["t25"] = nil
  289.         for _, data in pairs(storage.talents) do
  290.             if data.b["t23"] then
  291.                 data.b["t23"] = nil
  292.             end
  293.             if data.b["t24"] then
  294.                 data.b["t24"] = nil
  295.             end
  296.             if data.b["t25"] then
  297.                 data.b["t25"] = nil
  298.             end
  299.         end
  300.         for i, force_data in pairs(storage.forces) do
  301.             for id, item in pairs(force_data.items) do
  302.                 local item_data = storage.items[item.item]
  303.                 if item_data.requires and item_data.requires == "m-spell-pack" then
  304.                     force_data.money = force_data.money + get_sell_price(item.item)*item.count
  305.                     force_data.items[id] = nil
  306.                 end
  307.             end
  308.             for id, mod in pairs(force_data.talent_modifiers) do
  309.                 if mod.type == "spellpack" then
  310.                     force_data.talent_modifiers[id] = nil
  311.                 end
  312.             end
  313.             update_items(game.forces[i])
  314.         end
  315.         game.print("Removed spellpack talents and items :(")
  316.         if script.active_mods["m-spell-pack"] then
  317.             game.print("Please update Spell-Pack")
  318.         end
  319.     end
  320.  
  321.     refresh_forces()
  322.     for _, force in pairs(game.forces) do
  323.         if storage.talents[force.name] then -- check if talents exist for this force
  324.             apply_talents(force)
  325.             update_items(force) -- update items as well, just in case
  326.         end
  327.     end
  328. end)
  329.  
  330. --function on_player_created(player)
  331. --
  332. --  refresh_forces()
  333. --end
  334.  
  335. script.on_event({defines.events.on_player_created,defines.events.on_forces_merged,defines.events.on_player_changed_force}, refresh_forces)
  336. --script.on_event(defines.events.on_console_chat, function(event)
  337. --  if event.message == "gold" then
  338. --      storage.forces[game.get_player(event.player_index).force.name].money = storage.forces[game.get_player(event.player_index).force.name].money+198000
  339. --      game.print(storage.forces[game.get_player(event.player_index).force.name].bonuses.critdamage)
  340. --  end
  341. --end)
  342.  
  343. --  create_equipment_gui(player)
  344. --  apply_talents(player)
  345.  
  346. script.on_event(defines.events.on_technology_effects_reset, function (event)
  347.     local force = event.force
  348.     local force_name = force.name
  349.     if not storage.forces or not storage.forces[force_name] then return end
  350.     for _, modifier in pairs(storage.forces[force_name].modifiers) do
  351.         local mult = 1
  352.         if modifier.periodical then
  353.             mult = modifier.periodical
  354.         end
  355.         if modifier.type == "force" then
  356.             add_modifier(force, modifier, mult)
  357.         end
  358.     end
  359.     for _, modifier in pairs(storage.forces[force_name].talent_modifiers) do
  360.         local mult = 1
  361.         if modifier.periodical then
  362.             mult = modifier.periodical
  363.         end
  364.         if modifier.type == "force" then
  365.             add_modifier(force, modifier, mult)
  366.         end
  367.     end
  368. end)
  369.  
  370. function remove_stickers(player)
  371.     if player.character and player.character.valid then
  372.         if not player.character.stickers then
  373.             return
  374.         end
  375.         for _, sticker in pairs(player.character.stickers) do
  376.             if sticker.name:sub(1,23) == "rpgitems-speed-sticker-" then
  377.                 sticker.destroy()
  378.             end
  379.         end
  380.     end
  381. end
  382.  
  383. -- TODO: optimize!
  384. script.on_nth_tick(6, function(event)
  385.     if not storage.forces then return end
  386.  
  387.     for _, data in pairs(storage.forces) do
  388.         local bonuses = data.bonuses
  389.         for _, player in pairs(data.players) do
  390.             if player.valid then
  391.                 local character = player.character
  392.                 if character and character.valid then
  393.                     character.health = character.health + bonuses.regen/10
  394.                     if bonuses.pctregen > 0 then
  395.                         character.health = character.health + (character.max_health + character.character_health_bonus + character.force.character_health_bonus )/1000*bonuses.pctregen
  396.                         --game.print((character.max_health + character.character_health_bonus + character.force.character_health_bonus )/1000*bonuses.pctregen*10)
  397.                     end
  398.                 end
  399.             end
  400.         end
  401.     end
  402.  
  403.     for _, player in pairs(game.connected_players) do
  404.         if player.character and player.character.valid and storage.forces[player.force.name] and storage.forces[player.force.name].bonuses.energy then
  405.             local target_entity = nil
  406.             local vehicle = player.vehicle
  407.             if vehicle and vehicle.grid and vehicle.grid.battery_capacity >0 and vehicle.grid.available_in_batteries < vehicle.grid.battery_capacity*0.98 then
  408.                 target_entity = vehicle
  409.             elseif player.character.grid then
  410.                 target_entity = player.character
  411.             end
  412.             if target_entity then
  413.                 local batteries = 0
  414.                 for _, eq in pairs(target_entity.grid.equipment) do
  415.                     if eq.type == "battery-equipment" and eq.energy < eq.max_energy then
  416.                         batteries=batteries+1
  417.                     end
  418.                 end
  419.                 --game.print(i)
  420.                 local remaining_electricity = storage.forces[player.force.name].bonuses.energy*10^2 -- 1/10 KJ
  421.                 for _=1, 2 do
  422.                     local used_electricity = 0
  423.                     local temp_batteries = 0
  424.                     for _, eq in pairs(target_entity.grid.equipment) do
  425.                         if eq.type == "battery-equipment" and eq.energy < eq.max_energy then
  426.                             local charging = min(remaining_electricity/batteries, eq.max_energy-eq.energy)
  427.                             eq.energy = eq.energy + charging
  428.                             used_electricity = used_electricity + charging
  429.                             if eq.energy < eq.max_energy then
  430.                                 temp_batteries = temp_batteries + 1
  431.                             end
  432.                         end
  433.                     end
  434.                     batteries = temp_batteries
  435.                     remaining_electricity = remaining_electricity - used_electricity
  436.                 end
  437.             end
  438.         end
  439.  
  440.         local player_index = player.index
  441.         local force_name = player.force.name
  442.         local force_data = storage.forces[force_name]
  443.         local player_momentum = storage.momentum[player_index]
  444.         local character = player.character
  445.         if force_data and force_data.bonuses.momentum > 0 and character and character.valid then
  446.             local position_x = player.position.x
  447.             local position_y = player.position.y
  448.             if not player_momentum then
  449.                 storage.momentum[player_index] = {
  450.                     position_x = position_x, position_y = position_y, momentum = 0
  451.                 }
  452.                 player_momentum = storage.momentum[player_index]
  453.             end
  454.  
  455.             if position_x == player_momentum.position_x and position_y == player_momentum.position_y then
  456.                 remove_stickers(player)
  457.                 player_momentum.momentum = 0
  458.             elseif event.tick % 60 == 0 and player_momentum.momentum < 5 then
  459.                 player_momentum.momentum = player_momentum.momentum + 1
  460.                 character.surface.create_entity{
  461.                     name = "rpgitems-speed-sticker-" .. player_momentum.momentum,
  462.                     position = player.position, target = character
  463.                 }
  464.             end
  465.             player_momentum.position_x = position_x
  466.             player_momentum.position_y = position_y
  467.         elseif player_momentum and player_momentum.momentum > 0 then
  468.             remove_stickers(player)
  469.             player_momentum.momentum = 0
  470.         end
  471.     end
  472. end)
  473.  
  474. --TODO: refactor/remove
  475. script.on_nth_tick(61, function()
  476.     for _, player in pairs(game.connected_players) do
  477.         local last = nil
  478.         for _, g in pairs(player.gui.left.children) do
  479.             last = g.name
  480.         end
  481.         if last ~= "rpgitems_item_gui" then
  482.             create_equipment_gui(player)
  483.         end
  484.     end
  485. end)
  486.  
  487. function disable_immolation(player)
  488.     storage.immolation[player.index] = nil
  489.     if player.character and player.character.valid and player.character.stickers then
  490.         for _, sticker in pairs(player.character.stickers) do
  491.             if sticker.name == "rpgitems-flamecloak-sticker" then
  492.                 sticker.destroy()
  493.             end
  494.         end
  495.     end
  496. end
  497.  
  498. local _entity_search_filter = {type = {"unit", "character"}, position = {}, radius = 6}
  499. script.on_nth_tick(25, function()
  500.     local immolations = storage.immolation
  501.     local mod_forces_data = storage.forces
  502.     for _, player in pairs(game.connected_players) do
  503.         if immolations[player.index] then
  504.             local player_force = player.force
  505.             local player_force_name = player_force.name
  506.             local immolation_bonus = mod_forces_data[player_force_name].bonuses.immolation -- TODO: Refactor?
  507.             local character = player.character
  508.             if immolation_bonus > 0 and character and character.valid then
  509.                 _entity_search_filter.position = player.position
  510.                 local enemies = player.surface.find_entities_filtered(_entity_search_filter)
  511.                 local damage_mult = player_force.get_ammo_damage_modifier("flamethrower") + 1
  512.                 for i=1, #enemies do
  513.                     local enemy = enemies[i]
  514.                     if enemy.valid then
  515.                         local enemy_force = enemy.force
  516.                         if enemy_force ~= player_force and not enemy_force.get_cease_fire(player_force) and not enemy_force.get_friend(player_force) then
  517.                             enemy.damage(immolation_bonus*25/60 *damage_mult, player_force_name, "fire")
  518.                         end
  519.                     end
  520.                 end
  521.             else
  522.                 disable_immolation(player)
  523.             end
  524.         end
  525.     end
  526. end)
  527.  
  528. -- TODO: Refactor
  529. local _stack_data = {name='', count=1}
  530. script.on_nth_tick(60, function()
  531.     for force_index, force_data in pairs(storage.forces) do
  532.         --income
  533.         --local player = game.players[id]
  534.         force_data.money = force_data.money + force_data.bonuses.income
  535.         local update = false
  536.         local item_cooldowns= force_data.item_cooldowns
  537.         for field, cd in pairs(item_cooldowns) do
  538.             cd = cd - 1
  539.             if cd <= 0 then
  540.                 cd = nil
  541.             end
  542.             item_cooldowns[field] = cd
  543.             update = true
  544.         end
  545.  
  546.         -- TODO: Refactor
  547.         local giveitem_cache = storage.giveitem_cache
  548.         for item, persec in pairs(force_data.giveitem) do
  549.             for _, player in pairs(force_data.players) do
  550.                 local player_index = player.index
  551.                 local cashed_item_player_data = giveitem_cache[player_index]
  552.                 if cashed_item_player_data == nil then
  553.                     local data = {}
  554.                     giveitem_cache[player_index] = data
  555.                     cashed_item_player_data = data
  556.                 end
  557.                 cashed_item_player_data[item] = (cashed_item_player_data[item] or 0) + persec
  558.             end
  559.         end
  560.  
  561.         local force = game.forces[force_index]
  562.         local money_caption = floor(force_data.money).."[img=rpgitems-coin]"
  563.         for _, player in pairs(force_data.players) do
  564.             if player.valid and player.connected then
  565.                 local rpgitems_item_gui = player.gui.left.rpgitems_item_gui
  566.                 if rpgitems_item_gui and rpgitems_item_gui.valid then
  567.                     rpgitems_item_gui.money.caption = money_caption
  568.                     --cooldowns
  569.                     if update then
  570.                         create_item_sprites(player)
  571.                     end
  572.                     --giveitem
  573.                     local cached_given_items = storage.giveitem_cache[player.index]
  574.                     local character = player.character
  575.                     local inventory = player.get_main_inventory()
  576.                     local player_insert = player.insert
  577.                     if inventory and character and character.valid and cached_given_items then
  578.                         local get_item_count = inventory.get_item_count
  579.                         for item, cached in pairs(cached_given_items) do
  580.                             local in_inventory = get_item_count(item)
  581.                             if cached >= 1 and in_inventory < 200 then
  582.                                 _stack_data.name = item
  583.                                 _stack_data.count = min(200-in_inventory,floor(cached))
  584.                                 local inserted = player_insert(_stack_data)
  585.                                 cached_given_items[item] = cached_given_items[item] - inserted
  586.                             end
  587.                         end
  588.                     end
  589.                 end
  590.             end
  591.         end
  592.     end
  593.  
  594.     local forces = storage.forces
  595.     local repairing_data = storage.repairing
  596.     for id, entity in pairs(repairing_data) do
  597.         if not entity or not entity.valid then
  598.             repairing_data[id] = nil
  599.         else
  600.             local force_name = entity.force.name
  601.             local force_data = forces[force_name]
  602.             local repair_bonus = force_data.bonuses.repair
  603.             if not force_data or repair_bonus == 0 or entity.get_health_ratio() == 1 then
  604.                 repairing_data[id] = nil
  605.             else
  606.                 entity.health = entity.health + entity.max_health / 100 * repair_bonus
  607.             end
  608.         end
  609.     end
  610. end)
  611.  
  612. script.on_nth_tick(150, function(event)
  613.     local tick = game.tick
  614.     local indestructible_characters = storage.indestructible_characters
  615.     for character, _tick in pairs(indestructible_characters) do
  616.         if tick >= _tick then
  617.             if character and character.valid then
  618.                 character.destructible = true
  619.             end
  620.             indestructible_characters[character] = nil
  621.         end
  622.     end
  623. end)
  624.  
  625. script.on_event(defines.events.on_player_main_inventory_changed, function(event)
  626.     if event.tick%60 == 0 then return end -- TODO: check
  627.  
  628.     local player_index = event.player_index
  629.     local player = game.get_player(player_index)
  630.     local player_items_cache = storage.giveitem_cache[player_index]
  631.     if not (player.character and player.character.valid and player_items_cache) then return end
  632.  
  633.     local inventory = player.get_main_inventory()
  634.     for item, cached in pairs(player_items_cache) do
  635.         local in_inventory = inventory.get_item_count(item)
  636.         if cached >= 1 and in_inventory < 200 then
  637.             local inserted = player.insert{name = item, count = min(200-in_inventory,floor(cached))}
  638.             player_items_cache[item] = player_items_cache[item] - inserted
  639.         end
  640.     end
  641. end)
  642.  
  643. function dbg(str)
  644.     if str == nil then
  645.         str = "nil"
  646.     elseif type(str) ~= "string" and type(str) ~= "number" then
  647.         if type(str)=="boolean" then
  648.             if str == true then
  649.                 str = "true"
  650.             else
  651.                 str = "false"
  652.             end
  653.         else
  654.             str=type(str)
  655.         end
  656.     end
  657.     game.players[1].print(game.tick.. " "..str)
  658. end
  659.  
  660. function distance(pos1,pos2)
  661.     local xdiff = pos1.x - pos2.x
  662.     local ydiff = pos1.y - pos2.y
  663.     return (xdiff * xdiff + ydiff * ydiff)^0.5
  664. end
  665.  
  666. function _print(str)
  667.     for _, player in pairs(game.connected_players) do
  668.         if player.valid and player.admin then
  669.             player.print(str)
  670.         end
  671.     end
  672. end
  673.  
  674. script.on_event(defines.events.on_gui_opened, function(event)
  675.     local entity = event.entity
  676.     if not (entity and entity.valid) then return end
  677.     if entity.name =="rpgitems-market" then
  678.         local player = game.get_player(event.player_index)
  679.         open_market(player)
  680.         unlock_items(player)
  681.     end
  682.     --if event.entity.name =="rpgitems-item-market" then
  683.     --  local player = game.get_player(event.player_index)
  684.     --  local gui = player.gui.center.add{type="frame", name = "rpgitems_item_market", direction = "vertical"}
  685.     --  itemselector_gui(gui, player)
  686.     --  player.opened = gui
  687.     --end
  688. end)
  689. --script.on_event(defines.events.script_raised_built, function()
  690. --
  691. --end)
  692. --script.on_event(defines.events.on_trigger_created_entity, function(event)
  693. --  if not event.entity then return end
  694. --end)
  695. script.on_event(defines.events.on_gui_closed, function(event)
  696.     if event.element and event.element.name =="rpgitems_market" then
  697.         event.element.destroy()
  698.         lock_items(game.get_player(event.player_index))
  699.     --elseif event.element and event.element.name == "rpgitems_item_market" then
  700.     --  event.element.destroy()
  701.     end
  702. end)
  703.  
  704.  
  705. script.on_event(defines.events.on_entity_died, function(event)
  706.     local force = event.force
  707.     local entity = event.entity
  708.     if not (force and entity and entity.valid) then return end
  709.     if entity.force == force then return end
  710.     local force_name = force.name
  711.     local force_data = storage.forces[force_name]
  712.     if not force_data then return end
  713.  
  714.     --local player_id = tonumber(force.name:sub(8))
  715.     force_data.money = force_data.money + 1
  716.  
  717.     -- player.create_local_flying_text{
  718.     --  position = entity.position,
  719.     --  time_to_live = 120,
  720.     --  text = "+1",
  721.     --  color = {r=0,g=0.7,b=0}
  722.     -- }
  723.     local caption = floor(force_data.money).."[img=rpgitems-coin]"
  724.     for _, player in pairs(force_data.players) do
  725.         local items_gui = player.gui.left.rpgitems_item_gui
  726.         if items_gui and items_gui.valid then
  727.             items_gui.money.caption = caption
  728.         end
  729.     end
  730. end, {
  731.     {filter = "type", type = "tree", invert = true, mode = "and"},
  732.     {filter = "type", type = "simple-entity", invert = true, mode = "and"},
  733. })
  734.  
  735.  
  736. ---@param player LuaPlayer
  737. ---@param surface LuaSurface?
  738. ---@param target_position? MapPosition
  739. ---@return boolean
  740. local function teleport_safely(player, surface, target_position)
  741.     if not (player and player.valid) then
  742.         return false
  743.     end
  744.     if surface then
  745.         if not surface.valid then
  746.             return false
  747.         end
  748.     else
  749.         surface = player.surface
  750.     end
  751.     if target_position == nil then
  752.         return false
  753.     end
  754.  
  755.     local character = player.character
  756.     if not (character and character.valid) then
  757.         -- Perhaps, its should beginning changed
  758.         player.teleport(target_position, surface)
  759.         return true
  760.     end
  761.  
  762.     local target
  763.     local is_vehicle = false
  764.     local vehicle = player.vehicle
  765.     local target_name
  766.     if vehicle and vehicle.valid and not vehicle.train and vehicle.get_driver() == character and vehicle.get_passenger() == nil then
  767.         target = vehicle
  768.         target_name = vehicle.name
  769.         is_vehicle = true
  770.     else
  771.         target = player
  772.         target_name = character.name
  773.     end
  774.     local radius = 200
  775.     local non_colliding_position = surface.find_non_colliding_position(target_name, target_position, radius, 5)
  776.  
  777.     if not non_colliding_position then
  778.         -- TODO: add localization
  779.         player.print("It's not possible to teleport you because there's not enough space for your character")
  780.         return false
  781.     end
  782.  
  783.     if is_vehicle then
  784.         if vehicle.type == "spider-vehicle" then
  785.             target.stop_spider()
  786.         else
  787.             target.speed = 0
  788.         end
  789.     end
  790.     target.teleport(non_colliding_position, surface)
  791.     return true
  792. end
  793.  
  794.  
  795. ---@param event EventData.on_player_died
  796. script.on_event(defines.events.on_player_died, function(event)
  797.     local player = game.get_player(event.player_index)
  798.     if not (player and player.valid) then return end
  799.  
  800.     local market_gui = player.gui.center.rpgitems_market
  801.     if market_gui then market_gui.destroy() end
  802.  
  803.     local character = player.character
  804.     local target
  805.     if character and character.valid then
  806.         target = character
  807.     else
  808.         target = player
  809.     end
  810.  
  811.     if target.surface.find_entity("rpgitems-market", target.position) then
  812.         teleport_safely(player, nil, target.position)
  813.     end
  814. end)
  815.  
  816. function apply_armor(event, armor)
  817.     local entity = event.entity
  818.     if not (entity and entity.valid) then return end
  819.  
  820.     local grid = entity.grid
  821.     local bonus_healing = 0
  822.     if grid and grid.max_shield > 0 then
  823.         local actual_damage = event.original_damage_amount
  824.         local armor_inv = entity.get_inventory(defines.inventory.character_armor)[1]
  825.         if armor_inv.valid_for_read and armor_inv.prototype.resistances then
  826.             local event_damage_type = event.damage_type.name
  827.             if armor_inv.prototype.resistances[event_damage_type] then
  828.                 actual_damage = max(0, (event.original_damage_amount - armor_inv.prototype.resistances[event_damage_type].decrease) * (1-armor_inv.prototype.resistances[event_damage_type].percent))
  829.             end
  830.         end
  831.         local shield_healing = (actual_damage - event.final_damage_amount) *armor
  832.         bonus_healing = min(event.final_damage_amount, shield_healing)
  833.         shield_healing = shield_healing - bonus_healing
  834.         shield_healing = min(shield_healing,grid.max_shield - grid.shield)
  835.  
  836.         local missing_shield = grid.max_shield - grid.shield
  837.         if missing_shield > 0 then
  838.             for a, eq in pairs(grid.equipment) do
  839.                 if eq.type == "energy-shield-equipment" then
  840.                     eq.shield = eq.shield + (eq.max_shield - eq.shield)/missing_shield * shield_healing
  841.                 end
  842.             end
  843.         end
  844.     --  entity.health = entity.health + healing - shield_healing
  845.     --else
  846.     --  entity.health = entity.health + actual_damage*armor
  847.     end
  848.  
  849.     entity.health = entity.health + event.final_damage_amount*armor + bonus_healing
  850. end
  851.  
  852. -- TODO: optimize
  853. script.on_event(defines.events.on_entity_damaged, function(event)
  854.     local cause = event.cause
  855.     local entity = event.entity
  856.  
  857.     if not entity.valid then return end
  858.  
  859.     local force = entity.force
  860.     local force_data = storage.forces[force.name]
  861.     if force_data == nil then return end
  862.  
  863.     local force_bonuses = force_data.bonuses
  864.     if entity.type == "character" then
  865.         local damage = force_bonuses.thorns
  866.         if cause and damage > 0 and cause.valid and cause.health then
  867.             cause.damage(damage, force, event.damage_type.name)
  868.         end
  869.         -- local player = entity.player
  870.         --if event.damage_type.name:sub(1,4)=="osp_" then
  871.         --  local mres = storage.forces[player.force.name].bonuses.magic_resistance /(storage.forces[player.force.name].bonuses.magic_resistance+100)
  872.         --  entity.health = entity.health + event.final_damage_amount*mres
  873.         --else
  874.             local armor = force_bonuses.armor
  875.             apply_armor(event, armor / (armor+100))
  876.         --end
  877.     elseif force_data and force_bonuses.repair > 0 and entity.name ~= "RITEG-1" then
  878.         storage.repairing[entity.unit_number] = entity
  879.     end
  880.  
  881.     if not (cause and cause.valid) then return end
  882.     local force_data = storage.forces[cause.force.name]
  883.     if force_data == nil then return end
  884.  
  885.  
  886.     local force_bonuses = force_data.bonuses
  887.     local extradamage = 0
  888.     --if event.damage_type.name == "chardamage" then
  889.     --  local mult = storage.forces[force].bonuses.chardamage_mult+cause.force.get_turret_attack_modifier("character")
  890.     --  extradamage = storage.forces[force].bonuses.chardamage*mult + (mult-1)*8
  891.     --  extradamage = entity.damage(extradamage, cause.force, "physical")
  892.     --end
  893.     if random() < force_bonuses.stun * (cause.type == "character" and 6 or 2) then
  894.         --game.print(storage.forces[force].bonuses.stun * (cause.type == "character" and 2 or 1))
  895.         if entity.type == "unit" or entity.type == "character" then
  896.             entity.surface.create_entity{
  897.                 name="rpgitems-stun-sticker", position=entity.position, target=entity
  898.             }
  899.         end
  900.     end
  901.  
  902.     if cause.type == "character" then
  903.         if force_bonuses.pctlifesteal > 0 then
  904.             cause.health = cause.health + (event.final_damage_amount + extradamage)/100*force_bonuses.pctlifesteal
  905.         end
  906.         if force_bonuses.lifesteal > 0 then
  907.             cause.health = cause.health + force_bonuses.lifesteal
  908.         end
  909.     end
  910.  
  911.     if entity.has_flag("breaths-air") and random() < force_bonuses.crit then
  912.         local pos =  entity.position
  913.         local surface = entity.surface
  914.         --local player_mult = 1
  915.         --if event.
  916.         extradamage = entity.damage((event.original_damage_amount+extradamage)*(1+force_bonuses.critdamage), cause.force, event.damage_type.name)
  917.         local dmg = extradamage + event.final_damage_amount
  918.  
  919.         rendering.draw_text({
  920.             text = tostring(floor(dmg)),
  921.             time_to_live = 120,
  922.             surface = surface,
  923.             color = RED_COLOR,
  924.             target = pos
  925.         })
  926.     end
  927. end, {
  928.     {filter = "final-damage-amount", comparison = ">", value = 0, mode = "and"},
  929.     {filter = "final-health", comparison = ">", value = 0, mode = "and"},
  930.     {filter = "damage-type", type = "fire", invert = true, mode = "and"},
  931.     {filter = "damage-type", type = "acid", invert = true, mode = "and"},
  932. })
  933.  
  934. script.on_event(defines.events.on_pre_player_died, function(event)
  935.     local player = game.get_player(event.player_index)
  936.     local force_name = player.force.name
  937.     local force_data = storage.forces[force_name]
  938.     if not (force_data and force_data.bonuses.revive > 0) then return end
  939.  
  940.     local item_cooldowns = force_data.item_cooldowns
  941.     if not item_cooldowns["rpgitems_crusader"] and not item_cooldowns["rpgitems_crusader_spepa"] then
  942.         local level = min(5, force_data.bonuses.revive)
  943.         local cdr = 0
  944.         if remote.interfaces["spell-pack"] then
  945.             local players = remote.call("spell-pack","get","players")
  946.             cdr = players[event.player_index].cdr / 2
  947.         end
  948.         local cooldown = 300 * (1-cdr)
  949.         item_cooldowns["rpgitems_crusader"] = cooldown
  950.         item_cooldowns["rpgitems_crusader_spepa"] = cooldown
  951.  
  952.         local character = player.character
  953.         if character and character.valid then
  954.             character.health = 1
  955.             character.destructible = false
  956.             character.surface.create_entity{name = "rpgitems-halo-sticker-"..level, position= player.position, target = character}
  957.             storage.indestructible_characters[character] = event.tick+level*60
  958.         end
  959.     end
  960. end)
  961.  
Advertisement
Add Comment
Please, Sign In to add comment