mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-08 00:39:30 +02:00
1522 lines
57 KiB
Lua
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 |