Guest User

Untitled

a guest
Apr 21st, 2016
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.01 KB | None | 0 0
  1. require "defines"
  2. require "math"
  3.  
  4. delta_angle = math.pi/6 --angle in radians to put revived player from locomotive (0,pi) right side (-pi, 0) left side
  5.  
  6. delta_distance = 10.0 -- distance to put player from the original position
  7.  
  8. locomotive_search_distance = 1 -- distance to look for locomotive
  9.  
  10.  
  11. player_inventory_types = {
  12.     defines.inventory.player_main,
  13.     defines.inventory.player_quickbar,
  14.     defines.inventory.player_guns,
  15.     defines.inventory.player_ammo,
  16.     defines.inventory.player_armor,
  17.     defines.inventory.player_tools,
  18.     defines.inventory.player_trash}
  19.  
  20. -- Copies one LUAInventory to a second one with the same type
  21. function copy_inventory(inventory_from, inventory_to)
  22.     for i=1, #inventory_from do
  23.         inventory_to[i].set_stack(inventory_from[i])
  24.     end
  25. end
  26.  
  27. --Copy a player entity inventory to second one
  28. function copy_player_inventory(entity_from, entity_to)
  29.     for i =1, #player_inventory_types do
  30.         local type = player_inventory_types[i]
  31.         copy_inventory(
  32.             entity_from.get_inventory(type),
  33.             entity_to.get_inventory(type))
  34.     end
  35. end
  36.  
  37. -- Moves position by distance units in direction of an angle
  38. function move_position(position, angle, distance)
  39.     return {
  40.     x = position.x + distance * math.sin(angle),
  41.     y = position.y - distance * math.cos(angle)}
  42. end
  43.  
  44. -- Returns player who controls given character entity
  45. function get_player_for_character(character)
  46.     for _,player in ipairs(game.players) do
  47.         local pos_c = character.position
  48.         local pos_p = player.position
  49.         if pos_c.x == pos_p.x and pos_c.y == pos_p.y then
  50.             return player
  51.         end
  52.     end
  53. end
  54.  
  55. --Table of delayed actions activated by delayed_action_handler
  56. local delayed_actions = {}
  57.  
  58. --One handler for on_tick events which activates delayed actions, if there is no action it unregisteres itself
  59. function delayed_action_handler(event)
  60.     for action,delay in pairs(delayed_actions) do
  61.         delay = delay - 1
  62.         if delay < 0 then
  63.             action()
  64.             delayed_actions[action] = nil
  65.         else
  66.             delayed_actions[action] = delay
  67.         end
  68.     end
  69.     if next(delayed_actions) == nil then
  70.         script.on_event(defines.events.on_tick, nil)
  71.     end
  72.        
  73. end
  74.  
  75. --Adds action with a delay, also creates a handler if needed
  76. function create_delayed_action(delay, action)
  77.     if next(delayed_actions) == nil then
  78.         script.on_event(defines.events.on_tick, delayed_action_handler)
  79.     end
  80.     delayed_actions[action] = delay
  81. end
  82.  
  83.  
  84. --Main mod logic, implemented as an on_entity_died handler
  85. function knockback_player (event)
  86.     if event.entity.type == "player" then
  87.         local old_character = event.entity
  88.         local pos = old_character.position
  89.         local killed_player = get_player_for_character(old_character)
  90.         if not killed_player then
  91.             return
  92.         end
  93.         local r = locomotive_search_distance
  94.         local nearby_trains = killed_player.surface.find_entities_filtered{
  95.             area= {{pos.x - r, pos.y - r}, {pos.x + r, pos.y + r}},
  96.             type= "locomotive"}
  97.         if #nearby_trains == 0 then
  98.             return
  99.         end
  100.         local train_orientation = nearby_trains[1].orientation --cw train orientation in range [0,1>
  101.         local angle = train_orientation * 2 * math.pi + delta_angle
  102.        
  103.         local new_pos = move_position(pos, angle, delta_distance)
  104.         local new_character = killed_player.surface.create_entity{
  105.             name=old_character.name,
  106.             position = new_pos,
  107.             force = "player"}
  108.        
  109.         copy_player_inventory(old_character, new_character)
  110.         if killed_player.character then
  111.             game.set_game_state{game_finished=false, player_won=false, next_level=nil, can_continue=false}
  112.             --cause jerky movement in mp and doesn't disable respawn timer
  113.             killed_player.character = new_character
  114.  
  115.             --killed_player.print("SP game")
  116.         else
  117.             new_character.destructible = false
  118.             create_delayed_action (601, function ()
  119.                 copy_player_inventory(new_character, killed_player.character)
  120.                 killed_player.teleport(new_pos, new_character.surface)
  121.                 new_character.destroy()
  122.                 end)
  123.         end    
  124.     end
  125. end
  126. function register_event_handlers()
  127.     script.on_event(defines.events.on_entity_died, knockback_player)
  128. end
  129. register_event_handlers()
Advertisement
Add Comment
Please, Sign In to add comment