1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-08 00:39:30 +02:00
ComfyFactorio/maps/pirates/api_events.lua
Piratux 9f0158546d Disabled ore generation at sea
Changes:
- Classes that generate ore passively now don't generate ore when at sea
2022-07-26 21:59:42 +01:00

1997 lines
77 KiB
Lua

-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
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 SurfacesCommon = require 'maps.pirates.surfaces.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 Jailed = require 'utils.datastore.jail_data'
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 'maps.pirates.locally_maintained_comfy_forks.tick_tack_trap' --'enemy' force, but that's okay
local Public = {}
function Public.silo_die()
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({'pirates.loss_silo_destroyed'})
elseif (not destination.dynamic_data.rocketlaunched) and destination.static_params and destination.static_params.base_cost_to_undock and destination.static_params.base_cost_to_undock['launch_rocket'] and destination.static_params.base_cost_to_undock['launch_rocket'] == true then
Crew.try_lose({'pirates.loss_silo_destroyed_before_necessary_launch'})
elseif (not destination.dynamic_data.rocketlaunched) then
Common.notify_force(force, {'pirates.silo_destroyed'})
end
end
destination.dynamic_data.rocketsilos[1].die()
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 = final_damage_amount / 4
-- 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_die()
-- 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 event.cause.force.name ~= memory.enemy_force_name 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
-- --@TODO: somehow fix the fact that drones can repair the turret
-- end
local function protect_special_entities(event)
-- local memory = Memory.get_crew_memory()
local entity = event.entity
if event.cause and event.cause.valid and entity and entity.valid then
local surfacedata = Surfaces.SurfacesCommon.decode_surface_name(entity.surface.name)
-- local dest = Common.current_destination()
if surfacedata.type == Surfaces.enum.CROWSNEST or surfacedata.type == Surfaces.enum.LOBBY then
entity.health = entity.health + event.final_damage_amount
end
end
end
local function damage_to_silo(event)
local memory = Memory.get_crew_memory()
local entity = event.entity
if event.cause and event.cause.valid and entity and entity.valid and entity.force.name == memory.force_name then
local destination = Common.current_destination()
if destination.dynamic_data.rocketsilos and destination.dynamic_data.rocketsilos[1] and destination.dynamic_data.rocketsilos[1].valid and entity == Common.current_destination().dynamic_data.rocketsilos[1] then
if string.sub(event.cause.force.name, 1, 4) ~= 'crew' then
-- play alert sound for all crew members
if memory.seconds_until_alert_sound_can_be_played_again <= 0 then
memory.seconds_until_alert_sound_can_be_played_again = Balance.alert_sound_max_frequency_in_seconds
for _, player_index in pairs(memory.crewplayerindices) do
local player = game.players[player_index]
player.play_sound({path = 'utility/alert_destroyed', volume_modifier = 1})
end
end
if Common.entity_damage_healthbar(entity, event.original_damage_amount / Balance.silo_resistance_factor * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness))) <= 0 then
Public.silo_die()
else
destination.dynamic_data.rocketsilohp = memory.healthbars[entity.unit_number].health
end
else
entity.health = entity.prototype.max_health
end
end
end
end
local function damage_to_enemyboat_spawners(event)
local memory = Memory.get_crew_memory()
if memory.enemyboats and #memory.enemyboats > 0 then
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
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if eb.spawner and eb.spawner.valid and event.entity == eb.spawner then
-- if eb.spawner and eb.spawner.valid and event.entity == eb.spawner and eb.state == Structures.Boats.enum_state.APPROACHING then
local damage = event.final_damage_amount
local adjusted_damage = damage
adjusted_damage = adjusted_damage / 2.6
-- if event.cause.name == 'artillery-turret' then
-- adjusted_damage = adjusted_damage / 1
-- end
if Common.entity_damage_healthbar(event.entity, adjusted_damage) <= 0 then
event.entity.die()
end
end
end
end
end
end
end
local function damage_to_artillery(event)
local memory = Memory.get_crew_memory()
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 event.cause.force.name ~= memory.enemy_force_name then return end
-- play alert sound for all crew members
if memory.seconds_until_alert_sound_can_be_played_again <= 0 then
memory.seconds_until_alert_sound_can_be_played_again = Balance.alert_sound_max_frequency_in_seconds
for _, player_index in pairs(memory.crewplayerindices) do
local player = game.players[player_index]
player.play_sound({path = 'utility/alert_destroyed', volume_modifier = 1})
end
end
-- remove resistances:
-- event.entity.health = event.entity.health + event.final_damage_amount - event.original_damage_amount
if Common.entity_damage_healthbar(event.entity, event.original_damage_amount / Balance.cannon_resistance_factor * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness)), Memory.get_crew_memory().boat) <= 0 then
event.entity.die()
end
else
event.entity.health = event.entity.prototype.max_health --nothing else should damage it
end
end
local function damage_to_krakens(event)
if not event.entity then return end
if not event.entity.valid then return end
if not event.entity.name then return end
if 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 memory = Memory.get_crew_memory()
if event.entity.force.name ~= memory.enemy_force_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 == 'poison' then
-- if event.cause.name == 'artillery-turret' then
adjusted_damage = adjusted_damage / 1.25
elseif event.damage_type.name and (event.damage_type.name == 'explosion') then
adjusted_damage = adjusted_damage / 1.5
elseif event.damage_type.name and (event.damage_type.name == 'fire') then
adjusted_damage = adjusted_damage / 1.25
end
-- and additionally:
if event.cause.name == 'artillery-turret' then
adjusted_damage = adjusted_damage / 1.1
end
if event.damage_type.name and (event.damage_type.name == 'laser') then
adjusted_damage = adjusted_damage / 7 --laser turrets are in range. give some resistance
end
if Common.entity_damage_healthbar(event.entity, adjusted_damage) <= 0 then
Kraken.kraken_die(memory.healthbars[unit_number].id)
end
end
local function damage_to_players_changes(event)
local memory = Memory.get_crew_memory()
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
local player_index = event.entity.player.index
local class = memory.classes_table and memory.classes_table[player_index]
local player = game.players[player_index]
if not (player and player.valid and player.character and player.character.valid) then
return
end
local damage_multiplier = 1
--game.print('on damage info: {name: ' .. event.damage_type.name .. ', object_name: ' .. event.damage_type.object_name .. '}')
if event.damage_type.name == 'poison' then --make all poison damage stronger against players
damage_multiplier = damage_multiplier * Balance.poison_damage_multiplier
else
if class then
if class == Classes.enum.SCOUT then
damage_multiplier = damage_multiplier * Balance.scout_damage_taken_multiplier
-- elseif class == Classes.enum.MERCHANT then
-- damage_multiplier = damage_multiplier * 1.10
elseif class == Classes.enum.SAMURAI then
damage_multiplier = damage_multiplier * Balance.samurai_damage_taken_multiplier
elseif class == Classes.enum.HATAMOTO then
damage_multiplier = damage_multiplier * Balance.hatamoto_damage_taken_multiplier
elseif class == Classes.enum.ROC_EATER then
damage_multiplier = damage_multiplier * Balance.roc_eater_damage_taken_multiplier
elseif class == Classes.enum.IRON_LEG then
if memory.class_auxiliary_data[player_index] and memory.class_auxiliary_data[player_index].iron_leg_active then
damage_multiplier = damage_multiplier * Balance.iron_leg_damage_taken_multiplier
end
elseif class == Classes.enum.VETERAN then
local chance = Balance.veteran_on_hit_slow_chance
if Math.random() < chance then
-- only certain targets accept stickers
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
player.surface.create_entity{
name = 'slowdown-sticker',
position = player.character.position,
speed = 1.5,
force = player.force,
target = event.cause
}
end
end
-- else
-- damage_multiplier = damage_multiplier * (1 + Balance.bonus_damage_to_humans())
end
end
end
if event.cause.force.name == memory.enemy_force_name then
damage_multiplier = damage_multiplier * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness))
end --Enemy Forces
-- game.print('name: ' .. event.cause.name .. ' damage: ' .. event.final_damage_amount)
-- game.print('multiplier: ' .. damage_multiplier)
if damage_multiplier > 1 then
event.entity.health = event.entity.health - event.final_damage_amount * (damage_multiplier - 1)
elseif damage_multiplier < 1 and event.final_health > 0 then --lethal damage case isn't this easy
event.entity.health = event.entity.health + event.final_damage_amount * (1 - damage_multiplier)
end
-- deal with damage reduction on lethal damage for players
-- Piratux wrote this code — it tracks player health (except passive regen), and intervenes on a lethal damage event, so it should work most of the time.
local global_memory = Memory.get_global_memory()
if damage_multiplier < 1 and event.final_health <= 0 then
local damage_dealt = event.final_damage_amount * damage_multiplier
if damage_dealt < global_memory.last_players_health[player_index] then
event.entity.health = global_memory.last_players_health[player_index] - damage_dealt
end
end
global_memory.last_players_health[player_index] = event.entity.health
end
local function other_enemy_damage_bonuses(event)
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.surface then return end
if not event.cause.surface.valid then return end
if event.damage_type.name == 'impact' then return end --avoid circularity
local memory = Memory.get_crew_memory()
-- 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 event.cause.force.name ~= memory.enemy_force_name then return end --Enemy Forces
local bonusDamage = event.final_damage_amount * Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness)
if bonusDamage > 0 then
event.entity.damage(bonusDamage, event.cause.force, 'impact', event.cause)
end
end
local function damage_dealt_by_players_changes(event)
local memory = Memory.get_crew_memory()
if not event.cause then return end
if not event.cause.valid then return end
if not event.entity.valid then return end
if event.cause.name ~= 'character' then return end
local character = event.cause
local player = character.player
local physical = event.damage_type.name == 'physical'
local acid = event.damage_type.name == 'acid'
local player_index = player.index
local class = memory.classes_table and memory.classes_table[player_index]
if class and class == Classes.enum.SCOUT and event.final_health > 0 then --lethal damage must be unaffected
event.entity.health = event.entity.health + (1 - Balance.scout_damage_dealt_multiplier) * event.final_damage_amount
elseif class and (class == Classes.enum.SAMURAI or class == Classes.enum.HATAMOTO) then
local samurai = memory.classes_table[player_index] == Classes.enum.SAMURAI
local hatamoto = memory.classes_table[player_index] == Classes.enum.HATAMOTO
--==Note this!
if not (samurai or hatamoto) then return end
local no_weapon = (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))
local melee = (physical or acid) and no_weapon
local extra_damage_to_deal = 0
local big_number = 1000
local extra_physical_damage_from_research_multiplier = 1 + memory.force.get_ammo_damage_modifier('bullet')
if melee and event.final_health > 0 then
if physical then
if samurai then
extra_damage_to_deal = Balance.samurai_damage_dealt_with_melee * extra_physical_damage_from_research_multiplier
elseif hatamoto then
extra_damage_to_deal = Balance.hatamoto_damage_dealt_with_melee * extra_physical_damage_from_research_multiplier
end
elseif acid then --this hacky stuff is to implement repeated spillover splash damage, whilst getting around the fact that if ovekill damage takes something to zero health, we can't tell in that event how much double-overkill damage should be dealt by reading off its HP. This code assumes that characters only deal acid damage via this function.
extra_damage_to_deal = event.original_damage_amount * big_number
end
elseif (not melee) and event.final_health > 0 then
if samurai then
event.entity.health = event.entity.health + (1 - Balance.samurai_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
elseif hatamoto then
event.entity.health = event.entity.health + (1 - Balance.hatamoto_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
end
end
if extra_damage_to_deal > 0 then
if event.entity.health >= extra_damage_to_deal then
event.entity.damage(extra_damage_to_deal, character.force, 'impact', character) --using .damage rather than subtracting from health directly plays better with entities which use healthbars
else
local surplus = (extra_damage_to_deal - event.entity.health)*0.8
event.entity.die(character.force, character)
local nearest = player.surface.find_nearest_enemy{position = player.position, max_distance = 2, force = player.force}
if nearest and nearest.valid then
nearest.damage(surplus/big_number, character.force, 'acid', character)
end
end
end
end
if physical then
-- QUARTERMASTER BUFFS
local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = Balance.quartermaster_range, type = {'character'}}
for _, p2 in pairs(nearby_players) do
if p2.player and p2.player.valid then
local p2_index = p2.player.index
if event.entity.valid and player_index ~= p2_index and memory.classes_table[p2_index] and memory.classes_table[p2_index] == Classes.enum.QUARTERMASTER then
event.entity.damage((Balance.quartermaster_bonus_physical_damage - 1) * event.final_damage_amount, character.force, 'impact', character) --triggers this function again, but not physical this time
end
end
end
-- PISTOL BUFFS
if character.shooting_state.state ~= defines.shooting.not_shooting then
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 event.entity.valid and weapon.valid_for_read and ammo.valid_for_read and weapon.name == 'pistol' and (ammo.name == 'firearm-magazine' or ammo.name == 'piercing-rounds-magazine' or ammo.name == 'uranium-rounds-magazine') then
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
end
end
end
local function swamp_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 event.entity.force.name == memory.enemy_force_name)) then return end
local damage = event.final_damage_amount
event.entity.health = event.entity.health + damage
end
local function maze_walls_resistance(event)
-- local memory = Memory.get_crew_memory()
local entity = event.entity
if not entity.valid then return end
local destination = Common.current_destination()
if not (destination and destination.subtype and destination.subtype == Islands.enum.MAZE) then return end
if not (destination.surface_name == entity.surface.name) then return end
if not ((entity.type and entity.type == 'tree') or entity.name == 'rock-huge' or entity.name == 'rock-big' or entity.name == 'sand-rock-big') then return end
local damage = event.final_damage_amount
if (event.damage_type.name and (event.damage_type.name == 'explosion' or event.damage_type.name == 'poison')) then
event.entity.health = event.entity.health + damage
elseif event.damage_type.name and event.damage_type.name == 'fire' then
-- put out forest fires:
for _, e2 in pairs(entity.surface.find_entities_filtered({area = {{entity.position.x - 4, entity.position.y - 4},{entity.position.x + 4, entity.position.y + 4}}, name = "fire-flame-on-tree"})) do
if e2.valid then e2.destroy() end
end
else
if string.sub(event.cause.force.name, 1, 4) == 'crew' then --player damage only
event.entity.health = event.entity.health + damage * 0.9
end
end
end
-- functions like this need to be rewritten so they play nicely with healthbars:
-- local function damage_to_enemies(event)
-- local memory = Memory.get_crew_memory()
-- if not (event.entity and event.entity.valid and event.entity.force and event.entity.force.valid) then return end
-- if event.entity.force.name ~= memory.enemy_force_name then return end
-- local evo = memory.evolution_factor
-- if evo and evo > 1 and event.final_health > 0 then --lethal damage needs to be unaffected, else they never die
-- local surplus = evo - 1
-- local damage_multiplier = 1/(1 + Common.surplus_evo_biter_health_fractional_modifier(surplus))
-- if damage_multiplier < 1 then
-- event.entity.health = event.entity.health + event.final_damage_amount * (1 - damage_multiplier)
-- end
-- end
-- -- commented out as this is done elsewhere:
-- -- if event.damage_type.name == 'poison' then
-- -- event.entity.health = event.entity.health + event.final_damage_amount
-- -- end
-- end
local function event_on_entity_damaged(event)
local crew_id = nil
if not crew_id and event.entity.surface.valid then crew_id = SurfacesCommon.decode_surface_name(event.entity.surface.name).crewid end
if not crew_id and event.force.valid then crew_id = Common.get_id_from_force_name(event.force.name) end
if not crew_id and event.entity.valid then crew_id = Common.get_id_from_force_name(event.entity.force.name) 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
damage_to_silo(event)
damage_to_krakens(event)
damage_to_enemyboat_spawners(event)
if event.entity and event.entity.valid and event.entity.name and event.entity.name == 'artillery-turret' then
damage_to_artillery(event)
end
protect_special_entities(event)
if not event.entity.valid then return end -- need to call again, healthbar'd object might have been killed by script, so we shouldn't proceed now
if not event.entity.health then return end
if (event.entity and event.entity.valid and event.entity.name and event.entity.name == 'character') then
damage_to_players_changes(event)
else
other_enemy_damage_bonuses(event)
end
biters_chew_stuff_faster(event)
swamp_resist_poison(event)
maze_walls_resistance(event)
damage_dealt_by_players_changes(event)
-- damage_to_enemies(event)
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) -- The reason we might want to do this is because of algorithms like the labyrinth code, which make directionally biased patterns if you don't generate chunks in a random order
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 = Common.get_id_from_force_name(game.players[event.player_index].force.name) 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 player.valid then return end
local crew_id = Common.get_id_from_force_name(player.force.name)
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 player.surface.name == 'gulag' then
event.buffer.clear()
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, 38) == 1 then
tick_tack_trap(memory.enemy_force_name, entity.surface, entity.position)
return
end
local give = {}
if memory.classes_table and memory.classes_table[event.player_index] then
if memory.classes_table[event.player_index] == Classes.enum.LUMBERJACK then
give[#give + 1] = {name = 'wood', count = 1}
Classes.lumberjack_bonus_items(give)
-- elseif memory.classes_table[event.player_index] == Classes.enum.WOOD_LORD then
-- give[#give + 1] = {name = 'wood', count = 1}
-- give[#give + 1] = {name = 'iron-ore', count = 1}
-- give[#give + 1] = {name = 'copper-ore', count = 1}
-- give[#give + 1] = {name = 'coal', count = 1}
-- if Math.random(every_nth_tree_gives_coins) == 1 then
-- local a = 12
-- give[#give + 1] = {name = 'coin', count = a}
-- memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
-- end
end
end
if #give > 0 then
Common.give(player, give, entity.position)
end
else
local give = {}
local baseamount = 4
--minimum 1 wood
local amount = Math.clamp(1, Math.max(1, Math.ceil(available)), Math.ceil(baseamount * available/starting))
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}
Classes.lumberjack_bonus_items(give)
-- 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 + 3}
-- give[#give + 1] = {name = 'iron-ore', count = 1}
-- give[#give + 1] = {name = 'copper-ore', count = 1}
-- give[#give + 1] = {name = 'coal', count = 1}
-- if Math.random(every_nth_tree_gives_coins) == 1 then
-- local a = 12
-- give[#give + 1] = {name = 'coin', count = a}
-- memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
-- end
else
give[#give + 1] = {name = 'wood', count = amount}
if Math.random(Balance.every_nth_tree_gives_coins) == 1 then --tuned
local a = 5
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
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 = Balance.base_caught_fish_amount + Balance.master_angler_fish_bonus}, {name = 'coin', count = Balance.master_angler_coin_bonus}}, entity.position)
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.DREDGER then
local to_give = {{name = 'raw-fish', count = Balance.base_caught_fish_amount + Balance.dredger_fish_bonus}}
to_give[#to_give + 1] = Loot.dredger_loot()[1]
Common.give(player, to_give, entity.position)
else
Common.give(player, {{name = 'raw-fish', count = Balance.base_caught_fish_amount}}, 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 --no coins on first map, else the optimal strategy is to handmine everything there
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.PROSPECTOR then
local a = 3
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_ore = memory.playtesting_stats.coins_gained_by_ore + a
give[#give + 1] = {name = entity.name, count = 6}
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.CHIEF_EXCAVATOR then
local a = 4
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_ore = memory.playtesting_stats.coins_gained_by_ore + a
give[#give + 1] = {name = entity.name, count = 12}
else
if memory.overworldx > 0 then
local a = 1
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_ore = memory.playtesting_stats.coins_gained_by_ore + a
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, 35) == 1 then
tick_tack_trap(memory.enemy_force_name, 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
local a = 55
c2[#c2 + 1] = {name = 'coin', count = a, color = CoreData.colors.coin}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
if Math.random(1, 35) == 1 then
c2[#c2 + 1] = {name = 'crude-oil-barrel', count = 1, color = CoreData.colors.oil}
end
else
local a = 35
c2[#c2 + 1] = {name = 'coin', count = a, color = CoreData.colors.coin}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
if Math.random(1, 35*3) == 1 then
c2[#c2 + 1] = {name = 'crude-oil-barrel', count = 1, color = CoreData.colors.oil}
end
end
end
for k, v in pairs(c) do
if k == 'coal' and #c2 <= 1 then --if oil, then no coal
c2[#c2 + 1] = {name = k, count = v, color = CoreData.colors.coal}
elseif k == 'stone' then
c2[#c2 + 1] = {name = k, count = v, color = CoreData.colors.stone}
end
end
Common.give(player, c2, entity.position)
destination.dynamic_data.rock_material_remaining = available
if Surfaces.get_scope(destination).break_rock then
Surfaces.get_scope(destination).break_rock(entity.surface, entity.position, entity.name)
end
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
local entity_name = entity.name
local revenge_target
if event.cause and event.cause.valid and event.cause.name == 'character' then
revenge_target = event.cause
end
-- This gives enemy loot straight to combat robot owner's inventory instead of dropping it on the ground
if event.cause and (event.cause.name == 'defender' or event.cause.name == 'distractor' or event.cause.name == 'destroyer') then
if event.cause.combat_robot_owner and event.cause.combat_robot_owner.valid then
revenge_target = event.cause.combat_robot_owner
end
end
local class
if revenge_target and
revenge_target.valid and
revenge_target.player and
revenge_target.player.index and
memory.classes_table and
memory.classes_table[revenge_target.player.index]
then
class = memory.classes_table[revenge_target.player.index]
end
local class_is_chief = (class and class == Classes.enum.CHIEF) and true or false
-- no worm loot in the maze except for chiefs:
local maze = (destination.subtype and destination.subtype == Islands.enum.MAZE)
if maze and not (entity_name == 'biter-spawner' or entity_name == 'spitter-spawner') and not (class_is_chief) then return end
local iron_amount
local coin_amount
local fish_amount
if entity_name == 'small-worm-turret' then
iron_amount = 5
coin_amount = 50
fish_amount = 1 * Balance.chief_fish_received_for_worm_kill
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'medium-worm-turret' then
iron_amount = 20
coin_amount = 90
fish_amount = 1 * Balance.chief_fish_received_for_worm_kill
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'biter-spawner' or entity_name == 'spitter-spawner' then
iron_amount = 30
coin_amount = 100
fish_amount = 0 -- cooking spawners don't really fit class fantasy imo
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'big-worm-turret' then
iron_amount = 30
coin_amount = 140
fish_amount = 2 * Balance.chief_fish_received_for_worm_kill
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'behemoth-worm-turret' then
iron_amount = 50
coin_amount = 260
fish_amount = 3 * Balance.chief_fish_received_for_worm_kill
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif memory.overworldx > 0 then --avoid coin farming on first island
if entity_name == 'small-biter' then
-- if Math.random(2) == 1 then
-- coin_amount = 1
-- end
coin_amount = 1
fish_amount = 1 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'small-spitter' then
coin_amount = 1
fish_amount = 1 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'medium-biter' then
coin_amount = 2
fish_amount = 1 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'medium-spitter' then
coin_amount = 2
fish_amount = 1 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'big-biter' then
coin_amount = 4
fish_amount = 2 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'big-spitter' then
coin_amount = 4
fish_amount = 2 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'behemoth-biter' then
coin_amount = 8
fish_amount = 3 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'behemoth-spitter' then
coin_amount = 8
fish_amount = 3 * Balance.chief_fish_received_for_biter_kill
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
end
end
local stack = {}
if iron_amount and iron_amount > 0 then
stack[#stack + 1] = {name = 'iron-plate', count = iron_amount}
end
if coin_amount and coin_amount > 0 then
stack[#stack + 1] = {name = 'coin', count = coin_amount}
end
if class_is_chief and fish_amount and fish_amount > 0 then
stack[#stack + 1] = {name = 'raw-fish', count = fish_amount}
end
local short_form = (not iron_amount) and true or false
if revenge_target then
Common.give(revenge_target.player, stack, revenge_target.player.position, short_form, entity.surface, entity.position)
else
if event.cause and event.cause.valid and event.cause.position then
Common.give(nil, stack, event.cause.position, short_form, entity.surface, entity.position)
else
Common.give(nil, stack, entity.position, short_form, 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()
if (destination and destination.type and destination.type == Surfaces.enum.ISLAND) then
local not_boat = true
if memory.enemyboats and #memory.enemyboats > 0 then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if eb.spawner and eb.spawner.valid and event.entity and event.entity.valid and event.entity == eb.spawner then
not_boat = false
break
end
end
end
if not_boat then
local extra_evo = Balance.evolution_per_nest_kill()
Common.increment_evo(extra_evo)
if destination.dynamic_data then
destination.dynamic_data.evolution_accrued_nests = destination.dynamic_data.evolution_accrued_nests + extra_evo
end
end
end
end
local function event_on_entity_died(event)
--== MODDING NOTE: event.cause is not always provided.
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 = Common.get_id_from_force_name(entity.force.name)
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) 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({'pirates.loss_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)
-- I think the only reason krakens don't trigger this right now is that they are destroyed rather than .die()
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.apply_flamer_nerfs()
local memory = Memory.get_crew_memory()
-- local difficulty = memory.difficulty
local force = memory.force
-- This code matches the vanilla game. Written by Hanakocz I think.
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_tech_multipliers() + Balance.flamers_base_nerf())
force.set_turret_attack_modifier('flamethrower-turret', flamer_power * Balance.flamers_tech_multipliers() + Balance.flamers_base_nerf())
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 = Common.get_id_from_force_name(p_force.name)
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({"", '>> ', {'pirates.research_notification', event.research.localised_name}}, CoreData.colors.notify_force_light)
Public.apply_flamer_nerfs()
-- Public.research_apply_buffs(event) -- this is broken right now
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['slowdown-capsule'].enabled = false
p_force.recipes['nuclear-fuel'].enabled = false
-- p_force.recipes['rail'].enabled = false
p_force.recipes['speed-module'].enabled = false
p_force.recipes['tank'].enabled = false
p_force.recipes['cannon-shell'].enabled = false
p_force.recipes['explosive-cannon-shell'].enabled = false
-- and since we can't build tanks anyway, let's disable this for later:
p_force.recipes['uranium-cannon-shell'].enabled = false
p_force.recipes['explosive-uranium-cannon-shell'].enabled = false
end
local function event_on_player_joined_game(event)
local global_memory = Memory.get_global_memory()
local player = game.players[event.player_index]
--figure out if we should drop them back into a crew:
if (not Server.get_current_time()) then -- don't run this on servers because I'd need to negotiate that with the rest of Comfy
player.print({'pirates.thesixthroc_support_toast'}, {r=1, g=0.4, b=0.9})
end
if _DEBUG then
game.print('Debug mode on. Use /go to get started, /1 /4 /32 etc to change game speed.')
end
local crew_to_put_back_in = nil
for _, memory in pairs(global_memory.crew_memories) do
if Common.is_id_valid(memory.id) and memory.crewstatus and memory.crewstatus == Crew.enum.ADVENTURING and memory.temporarily_logged_off_characters[player.index] then
crew_to_put_back_in = memory.id
break
end
end
if crew_to_put_back_in then
Crew.join_crew(player, crew_to_put_back_in, true)
local memory = global_memory.crew_memories[crew_to_put_back_in]
if #memory.crewplayerindices <= 1 then
memory.playerindex_captain = player.index
end
if _DEBUG then log('putting player back in their old crew') end
else
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 game.tick == 0 then
Common.ensure_chunks_at(surface, spawnpoint, 5)
end
-- Auto-join the oldest crew:
local ages = {}
for _, memory in pairs(global_memory.crew_memories) do
if Common.is_id_valid(memory.id)
and memory.crewstatus
and memory.crewstatus == Crew.enum.ADVENTURING
and memory.capacity
and memory.crewplayerindices
and #memory.crewplayerindices < memory.capacity
and (not (memory.tempbanned_from_joining_data
and memory.tempbanned_from_joining_data[player.index]
and game.tick < memory.tempbanned_from_joining_data[player.index] + Common.ban_from_rejoining_crew_ticks)) then
ages[#ages+1] = {id = memory.id, age = memory.age, large = (memory.capacity >= Common.minimum_run_capacity_to_enforce_space_for)}
end
end
table.sort(
ages,
function(a, b) --true if a should be to the left of b
if a.large and (not b.large) then
return true
elseif (not a.large) and b.large then
return false
else
return a.age > b.age
end
end
)
if ages[1] then
Crew.join_crew(player, ages[1].id)
local memory = global_memory.crew_memories[ages[1].id]
if #memory.crewplayerindices <= 1 then
memory.playerindex_captain = player.index
end
if ages[2] then
if ages[1].large and (not ages[#ages].large) then
Common.notify_player_announce(player, {'pirates.goto_oldest_crew_with_large_capacity'})
else
Common.notify_player_announce(player, {'pirates.goto_oldest_crew'})
end
end
end
end
if not _DEBUG then
Gui.info.toggle_window(player)
end
global_memory.last_players_health[event.player_index] = player.character.health
-- 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 = Common.get_id_from_force_name(player.force.name)
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 not crew_id 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, false, true)
break
end
end
for _, id in pairs(memory.spectatorplayerindices) do
if player.index == id then
Crew.leave_spectators(player, true)
break
end
end
global_memory.last_players_health[event.player_index] = nil
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]
local jailed = Jailed.get_jailed_table()
if player.name and jailed and jailed[player.name] then
-- not quite sure this is necessary, but let's send their items to the crew:
Common.send_important_items_from_player_to_crew(player, true)
return
end
-- prevent connecting power between surfaces: (for the ship we do this automatically, but no need to let players do it in the general case:)
if not player.is_cursor_empty() then
if player.cursor_stack and player.cursor_stack.valid_for_read then
local blacklisted = {
['small-electric-pole'] = true,
['medium-electric-pole'] = true,
['big-electric-pole'] = true,
['substation'] = true,
}
if blacklisted[player.cursor_stack.name] then
player.get_main_inventory().insert(player.cursor_stack)
player.cursor_stack.clear()
end
end
if player.cursor_ghost then
player.cursor_ghost = nil
end
end
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 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
-- a way to make simple cars work
if vehicle.minable then
return
end
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
local crew_id = Common.get_id_from_force_name(player.force.name)
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
-- to avoid having chests on water, add a landfill tile underneath them
local landfill_tiles = {}
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 = memory.ancient_friendly_force_name}
if e and e.valid then
e.minable = false
e.rotatable = false
e.destructible = false
local water_tiles = surface.find_tiles_filtered{position = special.position, radius = 0.1, collision_mask = "water-tile"}
if water_tiles then
for _, t in pairs(water_tiles) do
landfill_tiles[#landfill_tiles + 1] = {name = "landfill", position = t.position}
end
end
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
if #landfill_tiles > 0 then
surface.set_tiles(landfill_tiles, true, false, false)
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 = Common.get_id_from_force_name(event.rocket.force.name)
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
local a = Balance.rocket_launch_coin_reward
Common.give_items_to_crew({{name = 'coin', count = a}})
memory.playtesting_stats.coins_gained_by_rocket_launches = memory.playtesting_stats.coins_gained_by_rocket_launches + a
end
local force = memory.force
local message = {'pirates.granted_2', {'pirates.granted_rocket_launch'}, Math.floor(Balance.rocket_launch_coin_reward/100)/10 .. 'k [item=coin]', Math.floor(destination.dynamic_data.rocketcoalreward/100)/10 .. 'k [item=coal]'}
Common.notify_force_light(force,message)
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
if destination.dynamic_data.rocketsilos then
for i = 1, #destination.dynamic_data.rocketsilos do
local s = destination.dynamic_data.rocketsilos[i]
if s and s.valid then
s.die()
end
end
destination.dynamic_data.rocketsilos = nil
end
end
local function event_on_built_entity(event)
local entity = event.created_entity
if not entity then return end
if not entity.valid then return end
if not event.player_index then return end
if not game.players[event.player_index] then return end
if not game.players[event.player_index].valid then return end
local player = game.players[event.player_index]
local crew_id = Common.get_id_from_force_name(player.force.name)
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
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.valid 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, {'pirates.error_build_undergrounds_on_boat'})
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 crew_id = Common.get_id_from_force_name(player.force.name)
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if player.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 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) then
return
end
-- their color was strobing, so now reset it to their chat color:
player.color = player.chat_color
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end --check if crew disbanded
if memory.game_lost then return end
memory.speed_boost_characters[player.index] = nil
Common.notify_player_expected(player, {'pirates.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
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) 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, {'pirates.respawn_speed_bonus_applied'})
end
)
local function event_on_player_respawned(event)
local player = game.players[event.player_index]
local crew_id = Common.get_id_from_force_name(player.force.name)
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 Boats.is_boat_at_sea() 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})
local global_memory = Memory.get_global_memory()
global_memory.last_players_health[event.player_index] = player.character.health
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, PiratesApiEvents.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)
return Public