1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-08 00:39:30 +02:00
ComfyFactorio/maps/pirates/interface.lua
danielmartin0 7a91abdb4c v1.0.4.0.1
2022-03-04 17:57:58 +00:00

1522 lines
57 KiB
Lua

local boats = require "maps.pirates.structures.boats.boats"
local simplex_noise = require "utils.simplex_noise"
local Memory = require 'maps.pirates.memory'
local Balance = require 'maps.pirates.balance'
local Math = require 'maps.pirates.math'
local Common = require 'maps.pirates.common'
local CoreData = require 'maps.pirates.coredata'
local Utils = require 'maps.pirates.utils_local'
local inspect = require 'utils.inspect'.inspect
local Ai = require 'maps.pirates.ai'
local Structures = require 'maps.pirates.structures.structures'
local Boats = require 'maps.pirates.structures.boats.boats'
local Surfaces = require 'maps.pirates.surfaces.surfaces'
local Progression = require 'maps.pirates.progression'
local Islands = require 'maps.pirates.surfaces.islands.islands'
local Roles = require 'maps.pirates.roles.roles'
local Gui = require 'maps.pirates.gui.gui'
local Sea = require 'maps.pirates.surfaces.sea.sea'
local Hold = require 'maps.pirates.surfaces.hold'
local Cabin = require 'maps.pirates.surfaces.cabin'
local Crowsnest = require 'maps.pirates.surfaces.crowsnest'
local Ores = require 'maps.pirates.ores'
local Parrot = require 'maps.pirates.parrot'
local Kraken = require 'maps.pirates.surfaces.sea.kraken'
local Crew = require 'maps.pirates.crew'
local Quest = require 'maps.pirates.quest'
local Shop = require 'maps.pirates.shop.shop'
local Loot = require 'maps.pirates.loot'
local Task = require 'utils.task'
local Token = require 'utils.token'
local Classes = require 'maps.pirates.roles.classes'
local Server = require 'utils.server'
-- local Modifers = require 'player_modifiers'
local tick_tack_trap = require 'functions.tick_tack_trap' --'enemy' force, but that's okay
local Public = {}
function Public.silo_died()
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local force = memory.force
if memory.game_lost == true then return end
destination.dynamic_data.rocketsilohp = 0
if destination.dynamic_data.rocketsilos and destination.dynamic_data.rocketsilos[1] and destination.dynamic_data.rocketsilos[1].valid then
local surface = destination.dynamic_data.rocketsilos[1].surface
surface.create_entity({name = 'big-artillery-explosion', position = destination.dynamic_data.rocketsilos[1].position})
if memory.boat and memory.boat.surface_name and surface.name == memory.boat.surface_name then
if CoreData.rocket_silo_death_causes_loss then
-- Crew.lose_life()
Crew.try_lose('silo destroyed')
elseif (not destination.dynamic_data.rocketlaunched) and destination.static_params and destination.static_params.cost_to_leave and destination.static_params.cost_to_leave['launch_rocket'] and destination.static_params.cost_to_leave['launch_rocket'] == true then
Crew.try_lose('silo destroyed before a necessary launch')
else
Common.notify_force(force, 'The silo was destroyed.')
end
end
destination.dynamic_data.rocketsilos[1].destroy()
destination.dynamic_data.rocketsilos = nil
end
end
function Public.damage_silo(final_damage_amount)
if final_damage_amount == 0 then return end
local destination = Common.current_destination()
local memory = Memory.get_crew_memory()
-- if we are doing the 'no damage' quest, then damage in the first 20 seconds after landing doesn't count:
if destination and destination.dynamic_data and destination.dynamic_data.quest_type == Quest.enum.NODAMAGE then
if not (destination.dynamic_data.timer and destination.dynamic_data.timeratlandingtime and destination.dynamic_data.timer > destination.dynamic_data.timeratlandingtime + 20) then return end
end
-- manual 'resistance:'
local final_damage_amount2 = Utils.deepcopy(final_damage_amount) / 5
destination.dynamic_data.rocketsilohp = Math.max(0, Math.floor(destination.dynamic_data.rocketsilohp - final_damage_amount2))
if destination.dynamic_data.rocketsilohp > destination.dynamic_data.rocketsilomaxhp then destination.dynamic_data.rocketsilohp = destination.dynamic_data.rocketsilomaxhp end
if destination.dynamic_data.rocketsilohp <= 0 then
-- if destination.dynamic_data.rocketsilohp <= 0 and (not destination.dynamic_data.rocketlaunched) then
Public.silo_died()
rendering.destroy(destination.dynamic_data.rocketsilohptext)
else
rendering.set_text(destination.dynamic_data.rocketsilohptext, 'HP: ' .. destination.dynamic_data.rocketsilohp .. ' / ' .. destination.dynamic_data.rocketsilomaxhp)
end
-- if destination.dynamic_data.rocketsilohp < destination.dynamic_data.rocketsilomaxhp / 2 and final_damage_amount > 0 then
-- Upgrades.trigger_poison()
-- end
end
local function biters_chew_stuff_faster(event)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
if not (event.cause and event.cause.valid and event.cause.force and event.cause.force.name and event.entity and event.entity.valid and event.entity.force and event.entity.force.name) then return end
if string.sub(event.cause.force.name, 1, 5) ~= 'enemy' then return end --Enemy Forces only
if (event.entity.force.index == 3 or event.entity.force.name == 'environment') then
event.entity.health = event.entity.health - event.final_damage_amount * 5
if destination and destination.type and destination.subtype and destination.type == Surfaces.enum.ISLAND and destination.subtype == Islands.enum.MAZE then
event.entity.health = event.entity.health - event.final_damage_amount * 10
end
elseif event.entity.name == 'pipe' then
event.entity.health = event.entity.health - event.final_damage_amount * 0.5
elseif event.entity.name == 'stone-furnace' then
event.entity.health = event.entity.health - event.final_damage_amount * 0.5
elseif event.entity.name == 'wooden-chest' or event.entity.name == 'stone-chest' or event.entity.name == 'steel-chest' then
event.entity.health = event.entity.health - event.final_damage_amount * 0.5
end
end
local function event_on_player_repaired_entity(event)
local entity = event.entity
if entity and entity.valid and entity.name and entity.name == 'artillery-turret' then
entity.health = entity.health - 2 --prevents repairing
end
end
local function silo_damage(event)
local memory = Memory.get_crew_memory()
if event.cause and event.cause.valid and event.entity and event.entity.valid then
if event.entity.force.name == memory.force_name then
local surfacedata = Surfaces.SurfacesCommon.decode_surface_name(event.entity.surface.name)
local dest = Common.current_destination()
if surfacedata.type == Surfaces.enum.CROWSNEST or surfacedata.type == Surfaces.enum.LOBBY then
event.entity.health = event.entity.health + event.final_damage_amount
elseif dest.dynamic_data.rocketsilos and dest.dynamic_data.rocketsilos[1] and dest.dynamic_data.rocketsilos[1].valid and event.entity == Common.current_destination().dynamic_data.rocketsilos[1] then
event.entity.health = event.entity.health + event.final_damage_amount
if string.sub(event.cause.force.name, 1, 4) ~= 'crew' then
Public.damage_silo(event.original_damage_amount)
end
end
end
end
end
local function enemyboat_spawners_invulnerable(event)
local memory = Memory.get_crew_memory()
if event.cause and event.cause.valid and event.entity and event.entity.valid then
if event.entity.force.name == memory.enemy_force_name then
if memory.enemyboats then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if eb.spawner and eb.spawner.valid and event.entity == eb.spawner and eb.state == Structures.Boats.enum_state.APPROACHING then
event.entity.health = event.entity.health + event.final_damage_amount
end
end
end
end
end
end
local function artillery_damage(event)
local memory = Memory.get_crew_memory()
if not (event.entity and event.entity.valid and event.entity.name and event.entity.name == 'artillery-turret') then return end
if not event.cause then return end
if not event.cause.valid then return end
if not event.cause.name then return end
if (event.cause.name == 'small-biter') or (event.cause.name == 'small-spitter') or (event.cause.name == 'medium-biter') or (event.cause.name == 'medium-spitter') or (event.cause.name == 'big-biter') or (event.cause.name == 'big-spitter') or (event.cause.name == 'behemoth-biter') or (event.cause.name == 'behemoth-spitter') then
if string.sub(event.cause.force.name, 1, 5) ~= 'enemy' then return end
-- remove resistances:
event.entity.health = event.entity.health + event.final_damage_amount - event.original_damage_amount
else
event.entity.health = event.entity.health + event.final_damage_amount --nothing else should damage it
end
end
local function kraken_damage(event)
local memory = Memory.get_crew_memory()
if not (event.entity and event.entity.valid and event.entity.name and event.entity.name == 'biter-spawner') then return end
if not event.cause then return end
if not event.cause.valid then return end
if not event.cause.name then return end
local surface_name = memory.boat and memory.boat.surface_name
if not (surface_name == memory.sea_name) then return end
local unit_number = event.entity.unit_number
local damage = event.final_damage_amount
local adjusted_damage = damage
if event.damage_type.name and (event.damage_type.name == 'explosion' or event.damage_type.name == 'poison') then
-- if event.cause.name == 'artillery-turret' then
adjusted_damage = adjusted_damage / 3
end
-- and additionally:
if event.cause.name == 'artillery-turret' then
adjusted_damage = adjusted_damage / 1.5
end
if event.damage_type.name and (event.damage_type.name == 'laser') then
adjusted_damage = adjusted_damage / 10 --laser turrets are in range
end
local healthbar = memory.healthbars[unit_number]
if not healthbar then return end
event.entity.health = event.entity.health + damage
local new_health = healthbar.health - adjusted_damage
healthbar.health = new_health
Common.update_healthbar_rendering(healthbar, new_health)
if new_health < 0 then
Kraken.kraken_die(healthbar.id, unit_number)
end
end
local function extra_player_damage(event)
local memory = Memory.get_crew_memory()
if not (event.entity and event.entity.valid and event.entity.name and event.entity.name == 'character') then return end
if not event.cause then return end
if not event.cause.valid then return end
if not event.cause.name then return end
-- if not (event.cause.name == 'small-biter') or (event.cause.name == 'small-spitter') or (event.cause.name == 'medium-biter') or (event.cause.name == 'medium-spitter') or (event.cause.name == 'big-biter') or (event.cause.name == 'big-spitter') or (event.cause.name == 'behemoth-biter') or (event.cause.name == 'behemoth-spitter') then return end
-- if string.sub(event.cause.force.name, 1, 5) ~= 'enemy' then return end --Enemy Forces
local player_index = event.entity.player.index
if memory.classes_table and memory.classes_table[player_index] then
if memory.classes_table[player_index] == Classes.enum.MERCHANT then
event.entity.health = event.entity.health - event.final_damage_amount * 0.5
elseif memory.classes_table[player_index] == Classes.enum.SCOUT then
event.entity.health = event.entity.health - event.final_damage_amount * 0.2
elseif memory.classes_table[player_index] == Classes.enum.IRON_LEG and event.final_health > 0 then --lethal damage is unaffected, as otherwise they can never die
local inv = event.entity.get_inventory(defines.inventory.character_main)
if not (inv and inv.valid) then return end
local count = inv.get_item_count('iron-ore')
if count and count >= 2500 then
event.entity.health = event.entity.health + event.final_damage_amount * 0.5
end
end --samurai health buff is elsewhere
end
event.entity.health = event.entity.health - event.final_damage_amount * Balance.bonus_damage_to_humans()
end
local function scout_damage_dealt_changes(event)
local memory = Memory.get_crew_memory()
local player_index = event.cause.player.index
if memory.classes_table and memory.classes_table[player_index] and memory.classes_table[player_index] == Classes.enum.SCOUT then
if event.final_health > 0 then --lethal damage is unaffected, as otherwise they can never kill
event.entity.health = event.entity.health + 0.5 * event.final_damage_amount
end
end
end
local function samurai_damage_dealt_changes(event)
local memory = Memory.get_crew_memory()
local character = event.cause
local player = character.player
local player_index = player.index
if memory.classes_table and memory.classes_table[player_index] and memory.classes_table[player_index] == Classes.enum.SAMURAI then
if event.damage_type.name == 'physical' and (not (character.get_inventory(defines.inventory.character_guns) and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index] and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index].valid_for_read)) then
event.entity.health = event.entity.health - 30
else
event.entity.health = event.entity.health + 0.66 * event.final_damage_amount
end
elseif memory.classes_table and memory.classes_table[player_index] and memory.classes_table[player_index] == Classes.enum.RONIN_SENSEI then
if event.damage_type.name == 'physical' and (not (character.get_inventory(defines.inventory.character_guns) and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index] and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index].valid_for_read)) then
event.entity.health = event.entity.health - 40
end
end
end
local function quartermaster_damage_dealt_changes(event)
local memory = Memory.get_crew_memory()
if not memory.classes_table then return end
local character = event.cause
local player = character.player
local player_index = player.index
local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = CoreData.quartermaster_range, type = {'character'}}
for _, p2 in pairs(nearby_players) do
local p2_index = p2.player.index
if player_index ~= p2_index and memory.classes_table[p2_index] and memory.classes_table[p2_index] == Classes.enum.QUARTERMASTER then
if event.damage_type.name == 'physical' then
event.entity.health = event.entity.health - 0.1 * event.final_damage_amount
end
end
end
end
local function resist_poison(event)
local memory = Memory.get_crew_memory()
local entity = event.entity
if not entity.valid then return end
if not (event.damage_type.name and event.damage_type.name == 'poison') then return end
local destination = Common.current_destination()
if not (destination and destination.subtype and destination.subtype == Islands.enum.SWAMP) then return end
if not (destination.surface_name == entity.surface.name) then return end
if not ((entity.type and entity.type == 'tree') or (event.entity.force and string.sub(event.entity.force.name, 1, 5) == 'enemy')) then return end
local damage = event.final_damage_amount
event.entity.health = event.entity.health + damage
end
local function event_on_entity_damaged(event)
-- figure out which crew this is about:
local crew_id = nil
if not crew_id and event.entity.surface.valid then crew_id = tonumber(string.sub(event.entity.surface.name, 1, 3)) or nil end
if not crew_id and event.force.valid then crew_id = tonumber(string.sub(event.force.name, -3, -1)) or nil end
if not crew_id and event.entity.valid then crew_id = tonumber(string.sub(event.entity.force.name, -3, -1)) or nil end
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local difficulty = memory.difficulty
if not event.entity.valid then return end
silo_damage(event)
if not event.entity.valid then return end -- need to call again, silo might be dead
if not event.entity.health then return end
enemyboat_spawners_invulnerable(event)
biters_chew_stuff_faster(event)
extra_player_damage(event)
artillery_damage(event)
resist_poison(event)
if string.sub(event.entity.force.name, 1, 5) == 'enemy' then
kraken_damage(event)
-- Balance.biter_immunities(event)
end
if not event.cause then return end
if not event.cause.valid then return end
if event.cause.name ~= 'character' then return end
scout_damage_dealt_changes(event)
samurai_damage_dealt_changes(event)
quartermaster_damage_dealt_changes(event)
if event.damage_type.name ~= 'physical' then return end --guns and melee... maybe more
local character = event.cause
if character.shooting_state.state == defines.shooting.not_shooting then return end
--@TODO: These might fail to be valid if player is dead or something
local weapon = character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index]
local ammo = character.get_inventory(defines.inventory.character_ammo)[character.selected_gun_index]
if not weapon.valid_for_read or not ammo.valid_for_read then return end
if weapon.name ~= 'pistol' then return end
if ammo.name ~= 'firearm-magazine' and ammo.name ~= 'piercing-rounds-magazine' and ammo.name ~= 'uranium-rounds-magazine' then return end
if not event.entity.valid then return end
event.entity.damage(event.final_damage_amount * (Balance.pistol_damage_multiplier() - 1), character.force, 'impact', character) --triggers this function again, but not physical this time
end
function Public.biter_immunities(event)
local memory = Memory.get_crew_memory()
-- local planet = memory.planet[1].type.id
-- if event.damage_type.name == 'fire' then
-- if planet == 14 then --lava planet
-- event.entity.health = event.entity.health + event.final_damage_amount
-- local fire = event.entity.stickers
-- if fire and #fire > 0 then
-- for i = 1, #fire, 1 do
-- if fire[i].sticked_to == event.entity and fire[i].name == 'fire-sticker' then fire[i].destroy() break end
-- end
-- end
-- -- else -- other planets
-- -- event.entity.health = Math.floor(event.entity.health + event.final_damage_amount - (event.final_damage_amount / (1 + 0.02 * memory.difficulty * memory.chronojumps)))
-- end
-- elseif event.damage_type.name == 'poison' then
-- if planet == 18 then --swamp planet
-- event.entity.health = event.entity.health + event.final_damage_amount
-- end
-- end
end
function Public.load_some_map_chunks(destination_index, fraction, force_load) --in a 'spear' from the left
--WARNING: if force_load is true, THIS DOES NOT PLAY NICELY WITH DELAYED TASKS. log(inspect{global_memory.working_id}) was observed to vary before and after this function.
force_load = force_load or false
local memory = Memory.get_crew_memory()
local destination_data = memory.destinations[destination_index]
if not destination_data then return end
local surface_name = destination_data.surface_name
if not surface_name then return end
local surface = game.surfaces[surface_name]
if not surface then return end
local w, h = surface.map_gen_settings.width, surface.map_gen_settings.height
local c = {x = 0, y = 0}
if destination_data.static_params and destination_data.static_params.islandcenter_position then
c = destination_data.static_params.islandcenter_position
w = w - 2 * Math.abs(c.x)
h = h - 2 * Math.abs(c.y)
end
local l = Math.max(Math.floor(w/32), Math.floor(h/32))
local i, j, s = 0, 0, {x = 0, y = 0}
while i < 4*l^2 and j <= fraction * w/32*h/32 do
i = i + 1
if s.y < 0 then
s.y = -s.y
elseif s.y > 0 then
s = {x = s.x + 1, y = 1 - s.y}
else
s = {x = 0, y = - (s.x + 1)}
end
if s.x <= w/32 and s.y <= h/32/2 and s.y >= -h/32/2 then
surface.request_to_generate_chunks({x = c.x - w/2 + 32*s.x, y = c.y + 32*s.y}, 0.1)
j = j + 1
end
end
if force_load then
surface.force_generate_chunk_requests() --WARNING: THIS DOES NOT PLAY NICELY WITH DELAYED TASKS. log(inspect{global_memory.working_id}) was observed to vary before and after this function.
end
end
function Public.load_some_map_chunks_random_order(destination_index, fraction)
local memory = Memory.get_crew_memory()
local destination_data = memory.destinations[destination_index]
if not destination_data then return end
local surface_name = destination_data.surface_name
if not surface_name then return end
local surface = game.surfaces[surface_name]
if not surface then return end
local shuffled_chunks
if not destination_data.dynamic_data then destination_data.dynamic_data = {} end
if not destination_data.dynamic_data.shuffled_chunks then
local w, h = surface.map_gen_settings.width, surface.map_gen_settings.height
local c = {x = 0, y = 0}
if destination_data.static_params and destination_data.static_params.islandcenter_position then
c = destination_data.static_params.islandcenter_position
w = w - 2 * Math.abs(c.x)
h = h - 2 * Math.abs(c.y)
end
local chunks_list = {}
for i = 0, Math.ceil(w/32 - 1), 1 do
for j = 0, Math.ceil(h/32 - 1), 1 do
table.insert(chunks_list, {x = c.x - w/2 + 32*i, y = c.y - h/2 + 32*j})
end
end
destination_data.dynamic_data.shuffled_chunks = Math.shuffle(chunks_list)
end
shuffled_chunks = destination_data.dynamic_data.shuffled_chunks
for i = 1, #shuffled_chunks do
if i > fraction * #shuffled_chunks then
break
end
surface.request_to_generate_chunks(shuffled_chunks[i], 0.2)
end
end
local function event_pre_player_mined_item(event)
-- figure out which crew this is about:
local crew_id = nil
if event.player_index and game.players[event.player_index].valid then crew_id = tonumber(string.sub(game.players[event.player_index].force.name, -3, -1)) or nil end
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
-- if memory.planet[1].type.id == 11 then --rocky planet
-- if event.entity.name == 'rock-huge' or event.entity.name == 'rock-big' or event.entity.name == 'sand-rock-big' then
-- Event_functions.trap(event.entity, false)
-- event.entity.destroy()
-- Event_functions.rocky_loot(event)
-- end
-- end
end
local function event_on_player_mined_entity(event)
if not event.player_index then return end
local player = game.players[event.player_index]
if not game.players[event.player_index].valid then return end
local crew_id = tonumber(string.sub(game.players[event.player_index].force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local entity = event.entity
if not entity.valid then return end
if entity.type == 'tree' then
if not event.buffer then return end
local available = destination.dynamic_data.wood_remaining
local starting = destination.static_params.starting_wood
if available and destination.type == Surfaces.enum.ISLAND then
if destination and destination.subtype and destination.subtype == Islands.enum.MAZE then
if Math.random(1, 300) == 1 then
tick_tack_trap(entity.surface, entity.position)
return
end
else
local give = {}
local baseamount = 4
--minimum 1 wood
local amount = Math.max(Math.ceil(Math.min(available, baseamount * available/starting)),1)
destination.dynamic_data.wood_remaining = destination.dynamic_data.wood_remaining - amount
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.LUMBERJACK then
give[#give + 1] = {name = 'wood', count = amount + 4}
if Math.random(7) == 1 then
give[#give + 1] = {name = 'coin', count = 20}
end
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.WOOD_LORD then
give[#give + 1] = {name = 'wood', count = amount + 8}
if Math.random(7) == 1 then
give[#give + 1] = {name = 'coin', count = 40}
end
else
give[#give + 1] = {name = 'wood', count = amount}
if Math.random(7) == 1 then --tuned
give[#give + 1] = {name = 'coin', count = 5}
end
end
Common.give(player, give, entity.position)
end
end
event.buffer.clear()
elseif entity.type == 'fish' then
if not event.buffer then return end
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.MASTER_ANGLER then
Common.give(player, {{name = 'raw-fish', count = 5}, {name = 'coin', count = 5}}, entity.position)
else
Common.give(player, {{name = 'raw-fish', count = 3}}, entity.position)
end
event.buffer.clear()
elseif entity.name == 'coal' or entity.name == 'stone' or entity.name == 'copper-ore' or entity.name == 'iron-ore' then
if not event.buffer then return end
local give = {}
if memory.overworldx > 0 then
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.PROSPECTOR then
give[#give + 1] = {name = 'coin', count = 4}
give[#give + 1] = {name = entity.name, count = 7}
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.CHIEF_EXCAVATOR then
give[#give + 1] = {name = 'coin', count = 8}
give[#give + 1] = {name = entity.name, count = 14}
else
if memory.overworldx > 0 then
give[#give + 1] = {name = 'coin', count = 1}
end
give[#give + 1] = {name = entity.name, count = 2}
end
else
give[#give + 1] = {name = entity.name, count = 2}
end
Common.give(player, give, entity.position)
event.buffer.clear()
elseif entity.name == 'rock-huge' or entity.name == 'rock-big' or entity.name == 'sand-rock-big' then
if not event.buffer then return end
local available = destination.dynamic_data.rock_material_remaining
local starting = destination.static_params.starting_rock_material
if available and destination.type == Surfaces.enum.ISLAND then
if destination and destination.subtype and destination.subtype == Islands.enum.MAZE then
if Math.random(1, 300) == 1 then
tick_tack_trap(entity.surface, entity.position)
return
end
else
local c = event.buffer.get_contents()
table.sort(c, function(a,b) return a.name < b.name end)
local c2 = {}
if memory.overworldx >= 0 then --used to be only later levels
if entity.name == 'rock-huge' then
c2[#c2 + 1] = {name = 'coin', count = 45, color = CoreData.colors.coin}
else
c2[#c2 + 1] = {name = 'coin', count = 30, color = CoreData.colors.coin}
end
end
for k, v in pairs(c) do
local color
if k == 'coal' then
color = CoreData.colors.coal
elseif k == 'stone' then
color = CoreData.colors.stone
end
local amount = Math.max(Math.min(available,Math.ceil(v * available/starting)),1)
--override, decided to remove this effect:
amount = v
c2[#c2 + 1] = {name = k, count = amount, color = color}
end
Common.give(player, c2, entity.position)
destination.dynamic_data.rock_material_remaining = available
Surfaces.get_scope(destination).break_rock(entity.surface, entity.position, entity.name)
end
end
event.buffer.clear()
end
end
local function shred_nearby_simple_entities(entity)
local memory = Memory.get_crew_memory()
if memory.evolution_factor < 0.25 then return end
local simple_entities = entity.surface.find_entities_filtered({type = {'simple-entity', 'tree'}, area = {{entity.position.x - 3, entity.position.y - 3},{entity.position.x + 3, entity.position.y + 3}}})
if #simple_entities == 0 then return end
for i = 1, #simple_entities, 1 do
if not simple_entities[i] then break end
if simple_entities[i].valid then
simple_entities[i].die(memory.enemy_force_name, simple_entities[i])
end
end
end
local function base_kill_rewards(event)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local entity = event.entity
if not (entity and entity.valid) then return end
if not (event.force and event.force.valid) then return end
-- no worm loot in the maze:
local maze = (destination and destination.subtype and destination.subtype == Islands.enum.MAZE)
if maze and not (entity.name == 'biter-spawner' or entity.name == 'spitter-spawner') then return end
local revenge_target
if event.cause and event.cause.valid and event.cause.name == 'character' then
revenge_target = event.cause
end
local iron_amount = 0
local coin_amount = 0
if memory.overworldx > 0 then
if entity.name == 'small-worm-turret' then
iron_amount = 5
coin_amount = 50
elseif entity.name == 'medium-worm-turret' then
iron_amount = 20
coin_amount = 90
elseif entity.name == 'biter-spawner' or entity.name == 'spitter-spawner'
then
iron_amount = 30
coin_amount = 75
elseif entity.name == 'big-worm-turret'
then
iron_amount = 30
coin_amount = 160
elseif entity.name == 'behemoth-worm-turret'
then
iron_amount = 50
coin_amount = 350
end
end
if iron_amount > 0 then
local stack = {{name = 'iron-plate', count = iron_amount}, {name = 'coin', count = coin_amount}}
if revenge_target then
Common.give(event.cause.player, stack)
else
Common.give(nil, stack, entity.position, entity.surface)
end
end
if (entity.name == 'biter-spawner' or entity.name == 'spitter-spawner') and entity.position and entity.surface and entity.surface.valid then
--check if its a boat biter entity
local boat_spawner = false
if memory.enemyboats then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if eb.spawner and eb.spawner.valid and event.entity == eb.spawner then
boat_spawner = true
break
end
end
end
if boat_spawner then
Ai.revenge_group(entity.surface, entity.position, revenge_target, 'biter', 0.3, 2)
elseif entity.name == 'biter-spawner' then
Ai.revenge_group(entity.surface, entity.position, revenge_target, 'biter')
else
Ai.revenge_group(entity.surface, entity.position, revenge_target, 'spitter')
end
end
end
local function spawner_died(event)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local extra_evo = Balance.evolution_per_biter_base_kill()
Common.increment_evo(extra_evo)
destination.dynamic_data.evolution_accrued_nests = destination.dynamic_data.evolution_accrued_nests + extra_evo
end
local function event_on_entity_died(event)
local entity = event.entity
if not (entity and entity.valid) then return end
if not (event.force and event.force.valid) then return end
local crew_id = nil
if not crew_id and event.force.valid then crew_id = tonumber(string.sub(event.force.name, -3, -1)) or nil end
if not crew_id and entity.valid then crew_id = tonumber(string.sub(entity.force.name, -3, -1)) or nil end
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if memory.id == 0 then return end
base_kill_rewards(event)
if memory.scripted_biters and entity.type == 'unit' and entity.force.name == memory.enemy_force_name then
memory.scripted_biters[entity.unit_number] = nil
end
if entity.force.index == 3 or entity.force.name == 'environment' then
if event.cause and event.cause.valid and event.cause.force.name == memory.enemy_force_name then
shred_nearby_simple_entities(entity)
end
end
if event.entity and event.entity.valid and event.entity.force and event.entity.force.name == memory.force_name then
if memory.boat and memory.boat.cannonscount and entity.name and entity.name == 'artillery-turret' then
memory.boat.cannonscount = memory.boat.cannonscount - 1
-- if memory.boat.cannonscount <= 0 then
-- Crew.try_lose()
-- end
Crew.try_lose('cannon destroyed')
end
end
if entity and entity.valid and entity.force and entity.force.name == memory.enemy_force_name then
if (entity.name == 'biter-spawner' or entity.name == 'spitter-spawner') then
spawner_died(event)
else
local destination = Common.current_destination()
if not (destination and destination.dynamic_data and destination.dynamic_data.quest_type and (not destination.dynamic_data.quest_complete)) then return end
if destination.dynamic_data.quest_type == Quest.enum.WORMS and entity.type == 'turret' then
destination.dynamic_data.quest_progress = destination.dynamic_data.quest_progress + 1
Quest.try_resolve_quest()
end
end
end
end
function Public.research_apply_buffs(event)
local memory = Memory.get_crew_memory()
local force = memory.force
if Balance.research_buffs[event.research.name] then
local tech = Balance.research_buffs[event.research.name]
-- @FIXME: This code is from another scenario but doesn't work
-- for k, v in pairs(tech) do
-- force[k] = force[k] + v
-- end
end
end
function Public.flamer_nerfs()
local memory = Memory.get_crew_memory()
local difficulty = memory.difficulty
local force = memory.force
local flame_researches = {
[1] = {name = 'refined-flammables-1', bonus = 0.2},
[2] = {name = 'refined-flammables-2', bonus = 0.2},
[3] = {name = 'refined-flammables-3', bonus = 0.2},
[4] = {name = 'refined-flammables-4', bonus = 0.3},
[5] = {name = 'refined-flammables-5', bonus = 0.3},
[6] = {name = 'refined-flammables-6', bonus = 0.4},
[7] = {name = 'refined-flammables-7', bonus = 0.2}
}
local flamer_power = 0
for i = 1, 6, 1 do
if force.technologies[flame_researches[i].name].researched then
flamer_power = flamer_power + flame_researches[i].bonus
end
end
flamer_power = flamer_power + (force.technologies[flame_researches[7].name].level - 7) * 0.2
-- force.set_ammo_damage_modifier('flamethrower', flamer_power - Balance.flamers_nerfs_size(memory.chronojumps, difficulty))
-- force.set_turret_attack_modifier('flamethrower-turret', flamer_power - Balance.flamers_nerfs_size(memory.chronojumps, difficulty))
end
local function event_on_research_finished(event)
-- figure out which crew this is about:
local research = event.research
local p_force = research.force
local crew_id = tonumber(string.sub(p_force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
-- using a localised string means we have to write this out (recall that "" signals concatenation)
memory.force.print({"", '>> ', event.research.localised_name, ' researched.'}, CoreData.colors.notify_force_light)
Public.flamer_nerfs()
Public.research_apply_buffs(event)
for _, e in ipairs(research.effects) do
local t = e.type
if t == 'ammo-damage' then
local category = e.ammo_category
local factor = Balance.player_ammo_damage_modifiers()[category]
if factor then
local current_m = p_force.get_ammo_damage_modifier(category)
local m = e.modifier
p_force.set_ammo_damage_modifier(category, current_m + factor * m)
end
elseif t == 'gun-speed' then
local category = e.ammo_category
local factor = Balance.player_gun_speed_modifiers()[category]
if factor then
local current_m = p_force.get_gun_speed_modifier(category)
local m = e.modifier
p_force.set_gun_speed_modifier(category, current_m + factor * m)
end
elseif t == 'turret-attack' then
local category = e.ammo_category
local factor = Balance.player_turret_attack_modifiers()[category]
if factor then
local current_m = p_force.get_turret_attack_modifier(category)
local m = e.modifier
p_force.set_turret_attack_modifier(category, current_m + factor * m)
end
end
end
-- even after research, force disable these:
-- p_force.recipes['underground-belt'].enabled = false
-- p_force.recipes['fast-underground-belt'].enabled = false
-- p_force.recipes['express-underground-belt'].enabled = false
p_force.recipes['pistol'].enabled = false
p_force.recipes['centrifuge'].enabled = false
-- p_force.recipes['flamethrower-turret'].enabled = false
p_force.recipes['locomotive'].enabled = false
p_force.recipes['car'].enabled = false
p_force.recipes['cargo-wagon'].enabled = false
p_force.recipes['rail'].enabled = true
end
local function event_on_player_joined_game(event)
local global_memory = Memory.get_global_memory()
local player = game.players[event.player_index]
-- if not memory.flame_boots[event.player_index] then
-- memory.flame_boots[event.player_index] = {}
-- end
-- memory.flame_boots[event.player_index] = {fuel = 1}
-- if not memory.flame_boots[event.player_index].steps then memory.flame_boots[event.player_index].steps = {} end
if player.character and player.character.valid then
player.character.destroy()
end
player.set_controller({type=defines.controllers.god})
player.create_character()
local spawnpoint = Common.lobby_spawnpoint
local surface = game.surfaces[CoreData.lobby_surface_name]
player.teleport(surface.find_non_colliding_position('character', spawnpoint, 32, 0.5) or spawnpoint, surface)
Roles.add_player_to_permission_group(player)
if not player.name then return end
-- start at Common.starting_island_spawnpoint or not?
-- if player.online_time == 0 then
Common.ensure_chunks_at(surface, spawnpoint, 5)
-- Auto-join the oldest crew:
local ages = {}
for _, mem in pairs(global_memory.crew_memories) do
if mem.id and mem.crewstatus and mem.crewstatus == Crew.enum.ADVENTURING and mem.capacity and mem.crewplayerindices and #mem.crewplayerindices < mem.capacity and (not (mem.tempbanned_from_joining_data and mem.tempbanned_from_joining_data[player.index] and game.tick < mem.tempbanned_from_joining_data[player.index] + Common.ban_from_rejoining_crew_ticks)) then
ages[#ages+1] = {id = mem.id, age = mem.age}
end
end
table.sort(
ages,
function(a, b) --true if a should be to the left of b
return a.age > b.age
end
)
if ages[1] then
Crew.join_crew(player, ages[1].id)
end
Roles.confirm_captain_exists(player)
if not _DEBUG then
Gui.info.toggle_window(player)
end
-- player.teleport(surface.find_non_colliding_position('character', spawnpoint, 32, 0.5), surface)
-- -- for item, amount in pairs(Balance.starting_items_player) do
-- -- player.insert({name = item, count = amount})
-- -- end
-- end
-- if player.surface.name ~= Common.current_destination().surface_name and string.sub(player.surface.name, 1, 10) ~= 'crowsnest-' then -- add other adventuring surfaces here
-- player.character = nil
-- player.set_controller({type=defines.controllers.god})
-- player.create_character()
-- player.teleport(surface.find_non_colliding_position('character', memory.force.get_spawn_position(surface), 32, 0.5), surface)
-- for item, amount in pairs(starting_items_player) do
-- player.insert({name = item, count = amount})
-- end
-- end
-- local tile = surface.get_tile(player.position)
-- if tile.valid then
-- if tile.name == 'out-of-map' then
-- player.teleport(surface.find_non_colliding_position('character', memory.force.get_spawn_position(surface), 32, 0.5), surface)
-- end
-- end
end
local function event_on_pre_player_left_game(event)
local player = game.players[event.player_index]
local global_memory = Memory.get_global_memory()
-- figure out which crew this is about:
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or 0
for k, proposal in pairs(global_memory.crewproposals) do
for k2, i in pairs(proposal.endorserindices) do
if i == event.player_index then
proposal.endorserindices[k2] = nil
if #proposal.endorserindices == 0 then
proposal = nil
global_memory.crewproposals[k] = nil
end
end
end
end
if crew_id == 0 then
if player.character and player.character.valid then
player.character.destroy()
end
return -- nothing more needed
end
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
for _, id in pairs(memory.crewplayerindices) do
if player.index == id then
Crew.leave_crew(player, true)
break
end
end
for _, id in pairs(memory.spectatorplayerindices) do
if player.index == id then
Crew.leave_spectators(player, true)
break
end
end
end
local function event_on_player_left_game(event)
-- n/a
end
-- local function on_player_changed_position(event)
-- local memory = Chrono_table.get_table()
-- if memory.planet[1].type.id == 14 then --lava planet
-- Event_functions.lava_planet(event)
-- end
-- end
local function on_player_changed_surface(event)
local player = game.players[event.player_index]
Roles.update_privileges(player)
end
function Public.player_entered_vehicle(player, vehicle)
if not vehicle then log('no vehicle') return end
-- if not vehicle.name then log('no vehicle') return end
-- if not vehicle.valid then log('vehicle invalid') return end
local player_relative_pos = {x = player.position.x - vehicle.position.x, y = player.position.y - vehicle.position.y}
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local player_boat_relative_pos
if memory and memory.boat and memory.boat.position then
player_boat_relative_pos = {x = player.position.x - memory.boat.position.x, y = player.position.y - memory.boat.position.y}
else
player_boat_relative_pos = {x = player.position.x - vehicle.position.x, y = player.position.y - vehicle.position.y}
end
local surfacedata = Surfaces.SurfacesCommon.decode_surface_name(player.surface.name)
if vehicle.name == 'car' then
if surfacedata.type ~= Surfaces.enum.CROWSNEST and surfacedata.type ~= Surfaces.enum.CABIN and surfacedata.type ~= Surfaces.enum.LOBBY then
if player_boat_relative_pos.x < -47 then
Surfaces.player_goto_cabin(player, {x = 2, y = player_relative_pos.y})
else
Surfaces.player_goto_crows_nest(player, player_relative_pos)
end
player.play_sound{path = "utility/picked_up_item"}
elseif surfacedata.type == Surfaces.enum.CROWSNEST then
Surfaces.player_exit_crows_nest(player, player_relative_pos)
player.play_sound{path = "utility/picked_up_item"}
elseif surfacedata.type == Surfaces.enum.CABIN then
Surfaces.player_exit_cabin(player, player_relative_pos)
player.play_sound{path = "utility/picked_up_item"}
end
vehicle.color = {148, 106, 52}
elseif vehicle.name == 'locomotive' then
if surfacedata.type ~= Surfaces.enum.HOLD and surfacedata.type ~= Surfaces.enum.LOBBY and Math.abs(player_boat_relative_pos.y) < 8 then --<8 in order not to enter holds of boats you haven't bought yet
Surfaces.player_goto_hold(player, player_relative_pos, 1)
player.play_sound{path = "utility/picked_up_item"}
elseif surfacedata.type == Surfaces.enum.HOLD then
local current_hold_index = surfacedata.destination_index
if current_hold_index >= memory.hold_surface_count then
Surfaces.player_exit_hold(player, player_relative_pos)
else
Surfaces.player_goto_hold(player, player_relative_pos, current_hold_index + 1)
end
player.play_sound{path = "utility/picked_up_item"}
end
end
player.driving = false
end
local function event_on_player_driving_changed_state(event)
local player = game.players[event.player_index]
local vehicle = event.entity
-- figure out which crew this is about:
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Public.player_entered_vehicle(player, vehicle)
end
function Public.event_on_chunk_generated(event)
local surface = event.surface
if not surface then return end
if not surface.valid then return end
if surface.name == 'nauvis' or surface.name == 'piratedev1' or surface.name == 'gulag' then return end
local seed = surface.map_gen_settings.seed
local name = surface.name
local surface_name_decoded = Surfaces.SurfacesCommon.decode_surface_name(name)
local type = surface_name_decoded.type
local subtype = surface_name_decoded.subtype
local chunk_destination_index = surface_name_decoded.destination_index
local crewid = surface_name_decoded.crewid
Memory.set_working_id(crewid)
local chunk_left_top = event.area.left_top
local width, height = nil, nil
local terraingen_coordinates_offset = {x = 0, y = 0}
local static_params = {}
local other_map_generation_data = {}
local scope
local memory = Memory.get_crew_memory()
if type == Surfaces.enum.ISLAND and memory.destinations and memory.destinations[chunk_destination_index] then
local destination = memory.destinations[chunk_destination_index]
scope = Surfaces.get_scope(destination)
static_params = destination.static_params
other_map_generation_data = destination.dynamic_data.other_map_generation_data or {}
terraingen_coordinates_offset = static_params.terraingen_coordinates_offset
width = static_params.width
height = static_params.height
end
if not scope then
scope = Surfaces[type]
end
local noise_params, terrain_fn, chunk_structures_fn
if scope then
if scope.Data then
if scope.Data.noiseparams then
noise_params = scope.Data.noiseparams
end
if (not width) and scope.Data.width then
width = scope.Data.width
end
if (not height) and scope.Data.height then
height = scope.Data.height
end
end
if scope.terrain then terrain_fn = scope.terrain end
if scope.chunk_structures then chunk_structures_fn = scope.chunk_structures end
end
if not width then
width = 999
log('no surface width? ' .. type)
end
if not height then height = 999 end
local tiles, entities, decoratives, specials = {}, {}, {}, {}
-- local noise_generator = nil
local noise_generator = Utils.noise_generator(noise_params, seed)
for y = 0.5, 31.5, 1 do
for x = 0.5, 31.5, 1 do
local p = {x = chunk_left_top.x + x, y = chunk_left_top.y + y}
if (p.x >= -width/2 and p.y >=-height/2 and p.x <= width/2 and p.y <= height/2) then
terrain_fn{p = Utils.psum{p, {1, terraingen_coordinates_offset}}, true_p = p, true_left_top = chunk_left_top, left_top = Utils.psum{chunk_left_top, {1, terraingen_coordinates_offset}}, noise_generator = noise_generator, static_params = static_params, tiles = tiles, entities = entities, decoratives = decoratives, specials = specials, seed = seed, other_map_generation_data = other_map_generation_data, iconized_generation = false}
else
tiles[#tiles + 1] = {name = 'out-of-map', position = Utils.psum{p, {1, terraingen_coordinates_offset}}}
end
end
end
chunk_structures_fn{true_left_top = chunk_left_top, left_top = Utils.psum{chunk_left_top, {1, terraingen_coordinates_offset}}, noise_generator = noise_generator, static_params = static_params, specials = specials, entities = entities, seed = seed, other_map_generation_data = other_map_generation_data, biter_base_density_scale = Balance.biter_base_density_scale()}
local tiles_corrected = {}
for i = 1, #tiles do
local t = tiles[i]
t.position = Utils.psum{t.position, {-1, terraingen_coordinates_offset}}
tiles_corrected[i] = t
end
local correct_tiles = true --tile borders etc
if #tiles_corrected > 0 then surface.set_tiles(tiles_corrected, correct_tiles) end
local destination = Common.current_destination()
if destination.dynamic_data then
if not destination.dynamic_data.structures_waiting_to_be_placed then
destination.dynamic_data.structures_waiting_to_be_placed = {}
end
for _, special in pairs(specials) do
-- recoordinatize:
special.position = Utils.psum{special.position, {-1, terraingen_coordinates_offset}}
if special.name and special.name == 'buried-treasure' then
if destination.dynamic_data.buried_treasure and crewid ~= 0 then
destination.dynamic_data.buried_treasure[#destination.dynamic_data.buried_treasure + 1] = {treasure = Loot.buried_treasure_loot(), position = special.position}
end
elseif special.name and special.name == 'chest' then
local e = surface.create_entity{name = 'wooden-chest', position = special.position, force = string.format('ancient-friendly-%03d', memory.id)}
if e and e.valid then
e.minable = false
e.rotatable = false
e.destructible = false
local inv = e.get_inventory(defines.inventory.chest)
local loot = Loot.wooden_chest_loot()
for i = 1, #loot do
local l = loot[i]
inv.insert(l)
end
end
end
if special.components then
destination.dynamic_data.structures_waiting_to_be_placed[#destination.dynamic_data.structures_waiting_to_be_placed + 1] = {data = special, tick = game.tick}
end
end
end
for i = 1, #entities do
local e = entities[i]
e.position = Utils.psum{e.position, {-1, terraingen_coordinates_offset}}
local e2 = e
-- e2.build_check_type = defines.build_check_type.ghost_revive
-- log(inspect(e2))
if surface.can_place_entity(e2) then
local ee = surface.create_entity(e)
if e.indestructible then
ee.destructible = false
end
end
end
local decoratives_corrected = {}
for i = 1, #decoratives do
local d = decoratives[i]
d.position = Utils.psum{d.position, {-1, terraingen_coordinates_offset}}
decoratives_corrected[i] = d
end
if #decoratives_corrected > 0 then surface.create_decoratives{decoratives = decoratives_corrected} end
end
local function event_on_rocket_launched(event)
-- figure out which crew this is about:
local crew_id = tonumber(string.sub(event.rocket.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
destination.dynamic_data.rocketlaunched = true
if memory.stored_fuel and destination.dynamic_data and destination.dynamic_data.rocketcoalreward then
memory.stored_fuel = memory.stored_fuel + destination.dynamic_data.rocketcoalreward
Common.give_reward_items{{name = 'coin', count = Balance.rocket_launch_coin_reward}}
end
local force = memory.force
Common.notify_force_light(force,'Granted ' .. Balance.rocket_launch_coin_reward .. ' [item=coin] and ' .. destination.dynamic_data.rocketcoalreward .. ' fuel.')
if destination.dynamic_data.quest_type == Quest.enum.TIME and (not destination.dynamic_data.quest_complete) then
destination.dynamic_data.quest_progressneeded = 1
Quest.try_resolve_quest()
end
if destination.dynamic_data.quest_type == Quest.enum.NODAMAGE and (not destination.dynamic_data.quest_complete) then
destination.dynamic_data.quest_progress = destination.dynamic_data.rocketsilohp
Quest.try_resolve_quest()
end
end
local event = require 'utils.event'
local function event_on_built_entity(event)
local entity = event.created_entity
if not entity or not entity.valid then
return
end
local crew_id = nil
if event.player_index and game.players[event.player_index].valid then crew_id = tonumber(string.sub(game.players[event.player_index].force.name, -3, -1)) or nil end
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local player = game.players[event.player_index]
if entity.type == 'entity-ghost' and entity.force and entity.force.valid then
entity.time_to_live = entity.force.ghost_time_to_live
end
if memory.boat and memory.boat.surface_name and player.surface == game.surfaces[memory.boat.surface_name] and entity.position then
if (entity.type and (entity.type == 'underground-belt')) or (entity.name == 'entity-ghost' and entity.ghost_type and (entity.ghost_type == 'underground-belt')) then
if Boats.on_boat(memory.boat, entity.position) then
-- if (entity.type and (entity.type == 'underground-belt' or entity.type == 'pipe-to-ground')) or (entity.name == 'entity-ghost' and entity.ghost_type and (entity.ghost_type == 'underground-belt' or entity.ghost_type == 'pipe-to-ground')) then
if not (entity.name and entity.name == 'entity-ghost') then
player.insert{name = entity.name, count = 1}
end
entity.destroy()
Common.notify_player_error(player, 'Undergrounds can\'t be built on the boat, due to conflicts with the boat movement code.')
return
end
end
end
-- hanas code for selective spidertrons:
-- local objective = Chrono_table.get_table()
-- if entity.name == 'spidertron' then
-- if objective.world.id ~= 7 or entity.surface.name == 'cargo_wagon' then
-- entity.destroy()
-- local player = game.players[event.player_index]
-- Alert.alert_player_warning(player, 8, {'chronosphere.spidertron_not_allowed'})
-- player.insert({name = 'spidertron', count = 1})
-- end
-- end
end
local function event_on_console_chat(event)
if not (event.message and event.player_index and game.players[event.player_index]) then return end
local global_memory = Memory.get_global_memory()
local player = game.players[event.player_index]
local tag = player.tag
if not tag then
tag = ''
end
local color = player.chat_color
-- if global.tournament_mode then
-- return
-- end
local message_force_name = player.force.name
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if message_force_name == 'player' then
local other_force_indices = global_memory.crew_active_ids
for _, index in pairs(other_force_indices) do
local recipient_force_name = global_memory.crew_memories[index].force_name
game.forces[recipient_force_name].print(player.name .. tag .. ' [LOBBY]: ' .. event.message, color)
end
else
game.forces.player.print(player.name .. tag .. ' [' .. memory.name .. ']: ' .. event.message, color)
end
end
local function event_on_market_item_purchased(event)
Shop.event_on_market_item_purchased(event)
end
local function event_on_player_used_capsule(event)
local player = game.players[event.player_index]
if not player or not player.valid then
return
end
local player_index = player.index
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (player.character and player.character.valid) then
return
end
local item = event.item
if not (item and item.name and item.name == 'raw-fish') then return end
if memory.classes_table and memory.classes_table[player_index] then
local class = memory.classes_table[player_index]
if class == Classes.enum.SAMURAI then
-- vanilla heal is 80HP
player.character.health = player.character.health + 200
elseif class == Classes.enum.RONIN_SENSEI then
player.character.health = player.character.health + 300
end
end
end
local remove_boost_movement_speed_on_respawn =
Token.register(
function(data)
local player = data.player
local crew_id = data.crew_id
if not (player and player.valid and player.character and player.character.valid) then
return
end
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if memory.game_lost then return end
memory.speed_boost_characters[player.index] = nil
-- their color was strobing, so now reset it to their chat color:
player.color = player.chat_color
Common.notify_player_expected(player, 'Respawn speed bonus removed.')
end
)
local boost_movement_speed_on_respawn =
Token.register(
function(data)
local player = data.player
local crew_id = data.crew_id
if not player or not player.valid then
return
end
if not player.character or not player.character.valid and player.character and player.character.valid then
return
end
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if memory.game_lost then return end
memory.speed_boost_characters[player.index] = true
Task.set_timeout_in_ticks(1050, remove_boost_movement_speed_on_respawn, {player = player, crew_id = crew_id})
Common.notify_player_expected(player, 'Respawn speed bonus applied.')
end
)
local function event_on_player_respawned(event)
local player = game.players[event.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local boat = memory.boat
if player.surface == game.surfaces[Common.current_destination().surface_name] then
if boat and boat.state == Boats.enum_state.ATSEA_SAILING then
-- assuming sea is always default:
local seasurface = game.surfaces[memory.sea_name]
player.teleport(memory.spawnpoint, seasurface)
elseif boat and (boat.state == Boats.enum_state.LANDED or boat.state == Boats.enum_state.RETREATING) then
if player.character and player.character.valid then
Task.set_timeout_in_ticks(360, boost_movement_speed_on_respawn, {player = player, crew_id = crew_id})
end
end
end
end
local event = require 'utils.event'
event.add(defines.events.on_built_entity, event_on_built_entity)
event.add(defines.events.on_entity_damaged, event_on_entity_damaged)
event.add(defines.events.on_entity_died, event_on_entity_died)
event.add(defines.events.on_player_repaired_entity, event_on_player_repaired_entity)
event.add(defines.events.on_player_joined_game, event_on_player_joined_game)
event.add(defines.events.on_pre_player_left_game, event_on_pre_player_left_game)
event.add(defines.events.on_player_left_game, event_on_player_left_game)
event.add(defines.events.on_pre_player_mined_item, event_pre_player_mined_item)
event.add(defines.events.on_player_mined_entity, event_on_player_mined_entity)
event.add(defines.events.on_research_finished, event_on_research_finished)
event.add(defines.events.on_player_changed_surface, on_player_changed_surface)
event.add(defines.events.on_player_driving_changed_state, event_on_player_driving_changed_state)
-- event.add(defines.events.on_player_changed_position, event_on_player_changed_position)
-- event.add(defines.events.on_technology_effects_reset, event_on_technology_effects_reset)
-- event.add(defines.events.on_chunk_generated, Interface.on_chunk_generated) --moved to main in order to make the debug properties clear
event.add(defines.events.on_rocket_launched, event_on_rocket_launched)
event.add(defines.events.on_console_chat, event_on_console_chat)
event.add(defines.events.on_market_item_purchased, event_on_market_item_purchased)
event.add(defines.events.on_player_respawned, event_on_player_respawned)
event.add(defines.events.on_player_used_capsule, event_on_player_used_capsule)
return Public