2022-03-19 21:20:55 +00:00
--luacheck: ignore
--luacheck ignores because tickinterval arguments are a code templating choice...
2021-10-13 09:21:53 +01:00
local Memory = require ' maps.pirates.memory '
local Structures = require ' maps.pirates.structures.structures '
local Boats = require ' maps.pirates.structures.boats.boats '
local Surfaces = require ' maps.pirates.surfaces.surfaces '
local Classes = require ' maps.pirates.roles.classes '
local Balance = require ' maps.pirates.balance '
local Common = require ' maps.pirates.common '
local CoreData = require ' maps.pirates.coredata '
local Math = require ' maps.pirates.math '
2022-03-19 21:20:55 +00:00
local _inspect = require ' utils.inspect ' . inspect
2021-10-13 09:21:53 +01:00
local Public = { }
2023-01-31 00:25:43 +02:00
-- Copied from modules
local function discharge_accumulators ( surface , position , force , power_needs )
local accumulators = surface.find_entities_filtered { name = ' accumulator ' , force = force , position = position , radius = 13 }
local power_drained = 0
power_needs = power_needs
for _ , accu in pairs ( accumulators ) do
if accu.valid then
if accu.energy > 3000000 and power_needs > 0 then
if power_needs >= 1000000 then
power_drained = power_drained + 1000000
accu.energy = accu.energy - 1000000
power_needs = power_needs - 1000000
else
power_drained = power_drained + power_needs
accu.energy = accu.energy - power_needs
end
elseif power_needs <= 0 then
break
end
end
end
return power_drained
end
-- NOTE: You can currently switch between classes shaman -> iron leg -> shaman, without losing your shaman charge, but I'm too lazy to fix.
2022-05-29 12:36:27 +01:00
function Public . class_update_auxiliary_data ( tickinterval )
2022-03-04 17:57:58 +00:00
local memory = Memory.get_crew_memory ( )
if not memory.classes_table then return end
2022-05-29 12:36:27 +01:00
local class_auxiliary_data = memory.class_auxiliary_data
2022-03-04 17:57:58 +00:00
local crew = Common.crew_get_crew_members ( )
2022-05-29 12:36:27 +01:00
local processed_players = { }
for _ , player in pairs ( crew ) do
local player_index = player.index
2022-10-11 20:52:23 +03:00
if Classes.get_class ( player_index ) == Classes.enum . IRON_LEG then
2023-01-31 00:25:43 +02:00
if ( not class_auxiliary_data [ player_index ] ) then
class_auxiliary_data [ player_index ] = { }
end
2022-05-29 12:36:27 +01:00
local data = class_auxiliary_data [ player_index ]
processed_players [ player_index ] = true
local check
if Common.validate_player_and_character ( player ) then
local inv = player.character . get_inventory ( defines.inventory . character_main )
if inv and inv.valid then
local count = inv.get_item_count ( ' iron-ore ' )
2022-06-02 16:18:53 +03:00
if count and count >= Balance.iron_leg_iron_ore_required then
2022-05-29 12:36:27 +01:00
check = true
end
end
end
if check then
data.iron_leg_active = true
else
data.iron_leg_active = false
end
2023-01-31 00:25:43 +02:00
elseif Classes.get_class ( player_index ) == Classes.enum . SHAMAN then
if ( not class_auxiliary_data [ player_index ] ) then
class_auxiliary_data [ player_index ] = { }
class_auxiliary_data [ player_index ] . shaman_charge = 0
end
local data = class_auxiliary_data [ player_index ]
processed_players [ player_index ] = true
if data.shaman_charge < Balance.shaman_max_charge then
2023-02-12 00:01:53 +02:00
-- charge from accumulators
2023-01-31 00:25:43 +02:00
local power_need = Balance.shaman_max_charge - data.shaman_charge
local energy = discharge_accumulators ( player.surface , player.position , memory.force , power_need )
data.shaman_charge = data.shaman_charge + energy
2023-02-12 00:01:53 +02:00
-- charge from sun pasively
data.shaman_charge = data.shaman_charge + ( 1 - player.surface . daytime ) * Balance.shaman_passive_charge * ( tickinterval / 60 )
data.shaman_charge = Math.min ( data.shaman_charge , Balance.shaman_max_charge )
2023-01-31 00:25:43 +02:00
end
2022-05-29 12:36:27 +01:00
end
end
for k , _ in pairs ( class_auxiliary_data ) do
if not processed_players [ k ] then
class_auxiliary_data [ k ] = nil
end
2022-03-07 09:50:25 +00:00
end
2022-05-29 12:36:27 +01:00
end
2022-03-07 09:50:25 +00:00
2022-05-29 12:36:27 +01:00
function Public . class_renderings ( tickinterval )
local memory = Memory.get_crew_memory ( )
if not memory.classes_table then return end
local class_renderings = memory.class_renderings
local crew = Common.crew_get_crew_members ( )
local processed_players = { }
2022-03-07 09:50:25 +00:00
2022-03-04 17:57:58 +00:00
for _ , player in pairs ( crew ) do
local player_index = player.index
2022-10-11 20:52:23 +03:00
local class = Classes.get_class ( player_index )
2022-05-29 12:36:27 +01:00
if class then
if not class_renderings [ player_index ] then class_renderings [ player_index ] = { } end
local rendering_data = class_renderings [ player_index ]
local r = rendering_data.rendering
local c = rendering_data.class
processed_players [ player_index ] = true
2023-01-31 00:25:43 +02:00
local data = memory.class_auxiliary_data [ player_index ]
-- if Common.validate_player_and_character(player) and (c ~= Classes.enum.IRON_LEG or (memory.class_auxiliary_data[player_index] and memory.class_auxiliary_data[player_index].iron_leg_active)) then
if Common.validate_player_and_character ( player ) then
2022-05-29 12:36:27 +01:00
if class == c then
if r and rendering.is_valid ( r ) then
rendering.set_target ( r , player.character )
end
2022-03-04 17:57:58 +00:00
else
2022-05-29 12:36:27 +01:00
if r and rendering.is_valid ( r ) then
rendering.destroy ( r )
end
if class == Classes.enum . QUARTERMASTER then
class_renderings [ player_index ] = {
rendering = rendering.draw_circle {
surface = player.surface ,
target = player.character ,
color = CoreData.colors . quartermaster_rendering ,
filled = false ,
2022-07-24 21:09:03 +01:00
radius = Balance.quartermaster_range ,
2022-05-29 12:36:27 +01:00
only_in_alt_mode = true ,
draw_on_ground = true ,
}
}
elseif class == Classes.enum . SAMURAI then
class_renderings [ player_index ] = {
rendering = rendering.draw_circle {
surface = player.surface ,
target = player.character ,
color = CoreData.colors . toughness_rendering ,
filled = false ,
2023-01-31 00:25:43 +02:00
radius = 1 - Balance.samurai_damage_taken_multiplier ,
2022-05-29 12:36:27 +01:00
only_in_alt_mode = false ,
draw_on_ground = true ,
}
}
elseif class == Classes.enum . HATAMOTO then
class_renderings [ player_index ] = {
rendering = rendering.draw_circle {
surface = player.surface ,
target = player.character ,
color = CoreData.colors . toughness_rendering ,
filled = false ,
2023-01-31 00:25:43 +02:00
radius = 1 - Balance.hatamoto_damage_taken_multiplier ,
2022-05-29 12:36:27 +01:00
only_in_alt_mode = false ,
draw_on_ground = true ,
}
}
2023-01-31 00:25:43 +02:00
elseif class == Classes.enum . IRON_LEG and data and data.iron_leg_active then
2022-05-29 12:36:27 +01:00
class_renderings [ player_index ] = {
rendering = rendering.draw_circle {
surface = player.surface ,
target = player.character ,
color = CoreData.colors . toughness_rendering ,
filled = false ,
2023-01-31 00:25:43 +02:00
radius = 1 - Balance.iron_leg_damage_taken_multiplier ,
only_in_alt_mode = false ,
draw_on_ground = true ,
}
}
elseif class == Classes.enum . MEDIC then
class_renderings [ player_index ] = {
rendering = rendering.draw_circle {
surface = player.surface ,
target = player.character ,
color = CoreData.colors . healing_radius_rendering ,
filled = false ,
radius = Balance.medic_heal_radius ,
only_in_alt_mode = true ,
draw_on_ground = true ,
}
}
elseif class == Classes.enum . DOCTOR then
class_renderings [ player_index ] = {
rendering = rendering.draw_circle {
surface = player.surface ,
target = player.character ,
color = CoreData.colors . healing_radius_rendering ,
filled = false ,
radius = Balance.doctor_heal_radius ,
only_in_alt_mode = true ,
draw_on_ground = true ,
}
}
elseif class == Classes.enum . SHAMAN and data and data.shaman_charge and data.shaman_charge > 0 then
local max_render_radius = 3
local radius = max_render_radius * ( data.shaman_charge / Balance.shaman_max_charge )
class_renderings [ player_index ] = {
rendering = rendering.draw_circle {
surface = player.surface ,
target = player.character ,
color = CoreData.colors . shaman_charge_rendering ,
filled = true ,
radius = radius ,
2022-05-29 12:36:27 +01:00
only_in_alt_mode = false ,
draw_on_ground = true ,
}
}
end
2022-03-04 17:57:58 +00:00
end
else
if r then
rendering.destroy ( r )
end
2022-05-29 12:36:27 +01:00
class_renderings [ player_index ] = nil
2022-03-04 17:57:58 +00:00
end
end
end
2022-03-07 09:50:25 +00:00
2022-05-29 12:36:27 +01:00
for k , data in pairs ( class_renderings ) do
if not processed_players [ k ] then
local r = data.rendering
if r and rendering.is_valid ( r ) then
rendering.destroy ( r )
end
class_renderings [ k ] = nil
2022-03-07 09:50:25 +00:00
end
end
2022-03-04 17:57:58 +00:00
end
2022-03-07 20:15:47 +00:00
2021-10-13 09:21:53 +01:00
function Public . update_character_properties ( tickinterval )
local memory = Memory.get_crew_memory ( )
local crew = Common.crew_get_crew_members ( )
for _ , player in pairs ( crew ) do
if Common.validate_player_and_character ( player ) then
local player_index = player.index
local character = player.character
2022-10-11 20:52:23 +03:00
local class = Classes.get_class ( player_index )
2022-10-30 23:25:30 +02:00
local speed_boost = Balance.base_extra_character_speed
if memory.speed_boost_characters and memory.speed_boost_characters [ player_index ] then
speed_boost = speed_boost * Balance.respawn_speed_boost
end
2022-07-28 11:28:38 +01:00
if class then
2022-06-02 16:07:17 +03:00
--local max_reach_bonus = 0
2021-10-13 09:21:53 +01:00
-- if memory.classes_table[player_index] == Classes.enum.DECKHAND then
-- max_reach_bonus = Math.max(max_reach_bonus, 6)
-- character.character_build_distance_bonus = 6
-- else
-- character.character_build_distance_bonus = 0
-- end
2022-07-28 11:28:38 +01:00
if class == Classes.enum . FISHERMAN then
2022-06-02 16:07:17 +03:00
character.character_reach_distance_bonus = Balance.fisherman_reach_bonus
2022-07-28 11:28:38 +01:00
elseif class == Classes.enum . MASTER_ANGLER then
2022-06-02 16:07:17 +03:00
character.character_reach_distance_bonus = Balance.master_angler_reach_bonus
2022-07-28 11:28:38 +01:00
elseif class == Classes.enum . DREDGER then
2022-06-02 16:07:17 +03:00
character.character_reach_distance_bonus = Balance.dredger_reach_bonus
2021-10-13 09:21:53 +01:00
else
2022-06-02 16:07:17 +03:00
character.character_reach_distance_bonus = 0
2021-10-13 09:21:53 +01:00
end
2022-10-30 23:25:30 +02:00
if class == Classes.enum . SCOUT then
2022-10-11 20:52:23 +03:00
speed_boost = speed_boost * Balance.scout_extra_speed
elseif ( class == Classes.enum . DECKHAND ) or ( class == Classes.enum . BOATSWAIN ) or ( class == Classes.enum . SHORESMAN ) then
local surfacedata = Surfaces.SurfacesCommon . decode_surface_name ( player.surface . name )
local type = surfacedata.type
local on_ship_bool = ( type == Surfaces.enum . HOLD ) or ( type == Surfaces.enum . CABIN ) or ( type == Surfaces.enum . CROWSNEST ) or ( player.surface . name == memory.boat . surface_name and Boats.on_boat ( memory.boat , player.position ) )
local hold_bool = ( type == Surfaces.enum . HOLD )
if class == Classes.enum . DECKHAND then
if on_ship_bool and ( not hold_bool ) then
speed_boost = speed_boost * Balance.deckhand_extra_speed
end
elseif class == Classes.enum . BOATSWAIN then
if hold_bool then
speed_boost = speed_boost * Balance.boatswain_extra_speed
end
elseif class == Classes.enum . SHORESMAN then
if not on_ship_bool then
speed_boost = speed_boost * Balance.shoresman_extra_speed
end
end
end
2021-10-13 09:21:53 +01:00
end
2022-10-30 23:25:30 +02:00
character.character_running_speed_modifier = speed_boost - 1
2022-03-14 12:44:30 +00:00
local health_boost = 0 -- base health is 250
2022-10-30 23:25:30 +02:00
character.character_health_bonus = health_boost
2022-03-19 21:20:55 +00:00
2022-03-14 12:44:30 +00:00
-- moved to damage resistance:
-- if memory.classes_table and memory.classes_table[player_index] then
-- local class = memory.classes_table[player_index]
-- if class == Classes.enum.SAMURAI then
-- health_boost = health_boost + 800
-- elseif class == Classes.enum.HATAMOTO then
-- health_boost = health_boost + 1300
-- end
-- end
2022-05-05 09:55:48 +01:00
-- Captain health boost:
-- if Common.is_captain(player) then
-- health_boost = health_boost + 50
-- end
2021-10-13 09:21:53 +01:00
2022-07-30 14:55:03 +01:00
-- == DO NOT DO THIS!: Removing inventory slots is evil. The player can spill inventory
-- if Common.is_captain(player) then
-- if player.character and player.character.valid then
-- player.character_inventory_slots_bonus = 20
-- end
-- else
-- if player.character and player.character.valid then
-- player.character_inventory_slots_bonus = 0
-- end
-- end
2021-10-13 09:21:53 +01:00
end
end
end
2021-10-24 15:27:57 +01:00
function Public . class_rewards_tick ( tickinterval )
2022-06-02 16:07:17 +03:00
--assuming tickinterval = 7 seconds for now
2021-10-13 09:21:53 +01:00
local memory = Memory.get_crew_memory ( )
2022-03-07 20:15:47 +00:00
local crew = Common.crew_get_crew_members ( )
2022-07-28 11:28:38 +01:00
for _ , player in pairs ( crew ) do
2022-10-11 20:52:23 +03:00
local class = Classes.get_class ( player.index )
2022-07-28 11:28:38 +01:00
if Common.validate_player_and_character ( player ) and
game.tick % tickinterval == 0 and
2022-10-11 20:52:23 +03:00
class and
not Boats.is_boat_at_sea ( ) and --it is possible to spend infinite time here, so don't give out freebies
(
class == Classes.enum . DECKHAND or
class == Classes.enum . SHORESMAN or
class == Classes.enum . BOATSWAIN or
class == Classes.enum . QUARTERMASTER
)
then --watch out for this line! (why?)
local surfacedata = Surfaces.SurfacesCommon . decode_surface_name ( player.surface . name )
local type = surfacedata.type
local on_ship_bool = ( type == Surfaces.enum . HOLD ) or ( type == Surfaces.enum . CABIN ) or ( type == Surfaces.enum . CROWSNEST ) or ( player.surface . name == memory.boat . surface_name and Boats.on_boat ( memory.boat , player.position ) )
local hold_bool = ( type == Surfaces.enum . HOLD )
if class == Classes.enum . DECKHAND and on_ship_bool and ( not hold_bool ) then
2023-01-29 23:01:48 +02:00
Classes.class_ore_grant ( player , Balance.deckhand_ore_grant_multiplier )
2022-10-11 20:52:23 +03:00
elseif class == Classes.enum . BOATSWAIN and hold_bool then
2023-01-29 23:01:48 +02:00
Classes.class_ore_grant ( player , Balance.boatswain_ore_grant_multiplier )
2022-10-11 20:52:23 +03:00
elseif class == Classes.enum . SHORESMAN and ( not on_ship_bool ) then
2023-01-29 23:01:48 +02:00
Classes.class_ore_grant ( player , Balance.shoresman_ore_grant_multiplier )
2022-10-11 20:52:23 +03:00
elseif class == Classes.enum . QUARTERMASTER then
local nearby_players = # player.surface . find_entities_filtered { position = player.position , radius = Balance.quartermaster_range , name = ' character ' }
if nearby_players > 1 then
2023-01-29 23:01:48 +02:00
Classes.class_ore_grant ( player , nearby_players - 1 )
2022-03-07 20:15:47 +00:00
end
end
2022-10-11 20:52:23 +03:00
end
2021-10-13 09:21:53 +01:00
2022-07-28 11:28:38 +01:00
-- Smoldering class is disabled
-- if memory.classes_table and memory.classes_table[player.index] then
-- if game.tick % tickinterval == 0 and Common.validate_player_and_character(player) then
-- if memory.classes_table[player.index] == Classes.enum.SMOLDERING then
-- local inv = player.get_inventory(defines.inventory.character_main)
-- if not (inv and inv.valid) then return end
-- local max_coal = 50
-- -- local max_transfer = 1
-- local wood_count = inv.get_item_count('wood')
-- local coal_count = inv.get_item_count('coal')
-- if wood_count >= 1 and coal_count < max_coal then
-- -- local count = Math.min(wood_count, max_coal-coal_count, max_transfer)
-- local count = 1
-- inv.remove({name = 'wood', count = count})
-- inv.insert({name = 'coal', count = count})
-- Common.flying_text_small(player.surface, player.position, '[item=coal]')
-- end
-- end
-- end
-- end
2021-10-13 09:21:53 +01:00
end
end
return Public