Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "defines"
- require "math"
- delta_angle = math.pi/6 --angle in radians to put revived player from locomotive (0,pi) right side (-pi, 0) left side
- delta_distance = 10.0 -- distance to put player from the original position
- locomotive_search_distance = 1 -- distance to look for locomotive
- player_inventory_types = {
- defines.inventory.player_main,
- defines.inventory.player_quickbar,
- defines.inventory.player_guns,
- defines.inventory.player_ammo,
- defines.inventory.player_armor,
- defines.inventory.player_tools,
- defines.inventory.player_trash}
- -- Copies one LUAInventory to a second one with the same type
- function copy_inventory(inventory_from, inventory_to)
- for i=1, #inventory_from do
- inventory_to[i].set_stack(inventory_from[i])
- end
- end
- --Copy a player entity inventory to second one
- function copy_player_inventory(entity_from, entity_to)
- for i =1, #player_inventory_types do
- local type = player_inventory_types[i]
- copy_inventory(
- entity_from.get_inventory(type),
- entity_to.get_inventory(type))
- end
- end
- -- Moves position by distance units in direction of an angle
- function move_position(position, angle, distance)
- return {
- x = position.x + distance * math.sin(angle),
- y = position.y - distance * math.cos(angle)}
- end
- -- Returns player who controls given character entity
- function get_player_for_character(character)
- for _,player in ipairs(game.players) do
- local pos_c = character.position
- local pos_p = player.position
- if pos_c.x == pos_p.x and pos_c.y == pos_p.y then
- return player
- end
- end
- end
- --Table of delayed actions activated by delayed_action_handler
- local delayed_actions = {}
- --One handler for on_tick events which activates delayed actions, if there is no action it unregisteres itself
- function delayed_action_handler(event)
- for action,delay in pairs(delayed_actions) do
- delay = delay - 1
- if delay < 0 then
- action()
- delayed_actions[action] = nil
- else
- delayed_actions[action] = delay
- end
- end
- if next(delayed_actions) == nil then
- script.on_event(defines.events.on_tick, nil)
- end
- end
- --Adds action with a delay, also creates a handler if needed
- function create_delayed_action(delay, action)
- if next(delayed_actions) == nil then
- script.on_event(defines.events.on_tick, delayed_action_handler)
- end
- delayed_actions[action] = delay
- end
- --Main mod logic, implemented as an on_entity_died handler
- function knockback_player (event)
- if event.entity.type == "player" then
- local old_character = event.entity
- local pos = old_character.position
- local killed_player = get_player_for_character(old_character)
- if not killed_player then
- return
- end
- local r = locomotive_search_distance
- local nearby_trains = killed_player.surface.find_entities_filtered{
- area= {{pos.x - r, pos.y - r}, {pos.x + r, pos.y + r}},
- type= "locomotive"}
- if #nearby_trains == 0 then
- return
- end
- local train_orientation = nearby_trains[1].orientation --cw train orientation in range [0,1>
- local angle = train_orientation * 2 * math.pi + delta_angle
- local new_pos = move_position(pos, angle, delta_distance)
- local new_character = killed_player.surface.create_entity{
- name=old_character.name,
- position = new_pos,
- force = "player"}
- copy_player_inventory(old_character, new_character)
- if killed_player.character then
- game.set_game_state{game_finished=false, player_won=false, next_level=nil, can_continue=false}
- --cause jerky movement in mp and doesn't disable respawn timer
- killed_player.character = new_character
- --killed_player.print("SP game")
- else
- new_character.destructible = false
- create_delayed_action (601, function ()
- copy_player_inventory(new_character, killed_player.character)
- killed_player.teleport(new_pos, new_character.surface)
- new_character.destroy()
- end)
- end
- end
- end
- function register_event_handlers()
- script.on_event(defines.events.on_entity_died, knockback_player)
- end
- register_event_handlers()
Advertisement
Add Comment
Please, Sign In to add comment