2021-10-13 10:21:53 +02:00
local Balance = require ' maps.pirates.balance '
2022-03-19 23:20:55 +02:00
local _inspect = require ' utils.inspect ' . inspect
2021-10-13 10:21:53 +02:00
local Memory = require ' maps.pirates.memory '
local Math = require ' maps.pirates.math '
local Common = require ' maps.pirates.common '
local Utils = require ' maps.pirates.utils_local '
local CoreData = require ' maps.pirates.coredata '
2022-03-19 23:20:55 +02:00
-- local Server = require 'utils.server'
2021-10-13 10:21:53 +02:00
local Public = { }
local enum = {
DECKHAND = 1 ,
FISHERMAN = 2 ,
SCOUT = 3 ,
SAMURAI = 4 ,
MERCHANT = 5 ,
SHORESMAN = 6 ,
BOATSWAIN = 7 ,
2022-02-24 21:39:03 +02:00
PROSPECTOR = 8 ,
2022-03-01 23:59:48 +02:00
LUMBERJACK = 9 ,
2022-03-04 19:57:58 +02:00
MASTER_ANGLER = 10 ,
WOOD_LORD = 11 ,
CHIEF_EXCAVATOR = 12 ,
2022-03-07 11:50:25 +02:00
HATAMOTO = 13 ,
2022-03-04 19:57:58 +02:00
IRON_LEG = 14 ,
QUARTERMASTER = 15 ,
2022-03-06 03:05:26 +02:00
DREDGER = 16 ,
2022-03-07 22:15:47 +02:00
SMOLDERING = 17 ,
GOURMET = 18 ,
2021-10-13 10:21:53 +02:00
}
Public.enum = enum
Public.Class_List = {
enum.DECKHAND ,
enum.FISHERMAN ,
enum.SCOUT ,
enum.SAMURAI ,
enum.MERCHANT ,
enum.SHORESMAN ,
enum.BOATSWAIN ,
2022-02-24 21:39:03 +02:00
enum.PROSPECTOR ,
2022-03-01 23:59:48 +02:00
enum.LUMBERJACK ,
2022-03-04 19:57:58 +02:00
enum.MASTER_ANGLER ,
enum.WOOD_LORD ,
enum.CHIEF_EXCAVATOR ,
2022-03-07 11:50:25 +02:00
enum.HATAMOTO ,
2022-03-04 19:57:58 +02:00
enum.IRON_LEG ,
enum.QUARTERMASTER ,
2022-03-06 03:05:26 +02:00
enum.DREDGER ,
2022-03-07 22:15:47 +02:00
enum.SMOLDERING ,
enum.GOURMET ,
2021-10-13 10:21:53 +02:00
}
Public.display_form = {
[ enum.DECKHAND ] = ' Deckhand ' ,
[ enum.FISHERMAN ] = ' Fisherman ' ,
[ enum.SCOUT ] = ' Scout ' ,
[ enum.SAMURAI ] = ' Samurai ' ,
[ enum.MERCHANT ] = ' Merchant ' ,
[ enum.SHORESMAN ] = ' Shoresman ' ,
[ enum.BOATSWAIN ] = ' Boatswain ' ,
2022-02-24 21:39:03 +02:00
[ enum.PROSPECTOR ] = ' Prospector ' ,
2022-03-01 23:59:48 +02:00
[ enum.LUMBERJACK ] = ' Lumberjack ' ,
2022-03-04 19:57:58 +02:00
[ enum.MASTER_ANGLER ] = ' Master Angler ' ,
[ enum.WOOD_LORD ] = ' Lord of the Woods ' ,
[ enum.CHIEF_EXCAVATOR ] = ' Chief Excavator ' ,
2022-03-07 11:50:25 +02:00
[ enum.HATAMOTO ] = ' Hatamoto ' ,
2022-03-04 19:57:58 +02:00
[ enum.IRON_LEG ] = ' Iron Leg ' ,
[ enum.QUARTERMASTER ] = ' Quartermaster ' ,
2022-03-06 03:05:26 +02:00
[ enum.DREDGER ] = ' Dredger ' ,
2022-03-07 22:15:47 +02:00
[ enum.SMOLDERING ] = ' Smoldering ' ,
[ enum.GOURMET ] = ' Gourmet ' ,
2021-10-13 10:21:53 +02:00
}
Public.explanation = {
2022-03-14 19:37:18 +02:00
[ enum.DECKHAND ] = ' They move faster and generate ore for the cabin whilst onboard above deck, but move slower offboard. ' ,
2021-10-13 10:21:53 +02:00
[ enum.FISHERMAN ] = ' They fish at greater distance. ' ,
2022-03-05 21:56:41 +02:00
[ enum.SCOUT ] = ' They are faster, but frail and deal less damage. ' ,
2022-03-04 19:57:58 +02:00
[ enum.SAMURAI ] = ' They are tough, and *with no weapon equipped* fight well by melee, but poorly otherwise. ' ,
2022-03-17 03:40:18 +02:00
[ enum.MERCHANT ] = ' They generate 40 doubloons per league. ' ,
2022-03-14 19:37:18 +02:00
[ enum.SHORESMAN ] = ' They move slightly faster and generate ore for the cabin whilst offboard, but move slower onboard. ' ,
[ enum.BOATSWAIN ] = ' They move faster and generate ore for the cabin whilst below deck, but move slower offboard. ' ,
2022-02-24 21:39:03 +02:00
[ enum.PROSPECTOR ] = ' They find more resources when handmining ore. ' ,
2022-03-01 23:59:48 +02:00
[ enum.LUMBERJACK ] = ' They find more resources when chopping trees. ' ,
2022-03-04 19:57:58 +02:00
[ enum.MASTER_ANGLER ] = ' They fish at much greater distance, and catch more. ' ,
[ enum.WOOD_LORD ] = ' They find many more resources when chopping trees. ' ,
[ enum.CHIEF_EXCAVATOR ] = ' They find many more resources when handmining ore. ' ,
2022-03-09 01:36:03 +02:00
[ enum.HATAMOTO ] = ' They are very tough, and *with no weapon equipped* fight well by melee, but poorly otherwise. ' ,
2022-03-13 03:44:32 +02:00
[ enum.IRON_LEG ] = ' They are very resistant to damage when carrying 3500 iron ore. ' ,
2022-03-14 19:37:18 +02:00
[ enum.QUARTERMASTER ] = ' They give nearby crewmates extra physical attack, and generate ore for the cabin for each one. ' ,
2022-03-07 11:50:25 +02:00
[ enum.DREDGER ] = ' They find surprising items when they fish. ' ,
2022-03-13 03:44:32 +02:00
[ enum.SMOLDERING ] = ' They periodically convert wood into coal, if they have less than 50 coal. ' ,
2022-03-14 19:37:18 +02:00
[ enum.GOURMET ] = ' They generate ore for the cabin by eating fish in fancy locations. ' ,
2021-10-13 10:21:53 +02:00
}
2022-03-04 19:57:58 +02:00
Public.class_unlocks = {
[ enum.FISHERMAN ] = { enum.MASTER_ANGLER } ,
[ enum.LUMBERJACK ] = { enum.WOOD_LORD } ,
2022-03-07 22:15:47 +02:00
-- [enum.PROSPECTOR] = {enum.CHIEF_EXCAVATOR}, --breaks the resource pressure in the game too strongly I think
2022-03-07 11:50:25 +02:00
[ enum.SAMURAI ] = { enum.HATAMOTO } ,
2022-03-06 03:05:26 +02:00
[ enum.MASTER_ANGLER ] = { enum.DREDGER } ,
2022-03-04 19:57:58 +02:00
}
Public.class_purchase_requirement = {
[ enum.MASTER_ANGLER ] = enum.FISHERMAN ,
[ enum.WOOD_LORD ] = enum.LUMBERJACK ,
2022-03-07 22:15:47 +02:00
-- [enum.CHIEF_EXCAVATOR] = enum.PROSPECTOR,
2022-03-07 11:50:25 +02:00
[ enum.HATAMOTO ] = enum.SAMURAI ,
2022-03-06 03:05:26 +02:00
[ enum.DREDGER ] = enum.MASTER_ANGLER ,
2022-03-04 19:57:58 +02:00
}
function Public . initial_class_pool ( )
return {
enum.DECKHAND ,
2022-03-07 22:15:47 +02:00
enum.DECKHAND , --good for afk players
enum.SHORESMAN ,
enum.SHORESMAN ,
enum.QUARTERMASTER ,
2022-03-04 19:57:58 +02:00
enum.FISHERMAN ,
enum.SCOUT ,
enum.SAMURAI ,
2022-03-09 01:36:03 +02:00
-- enum.MERCHANT, --not interesting, breaks coin economy
2022-03-04 19:57:58 +02:00
enum.BOATSWAIN ,
enum.PROSPECTOR ,
enum.LUMBERJACK ,
enum.IRON_LEG ,
2022-03-07 22:15:47 +02:00
enum.SMOLDERING ,
enum.GOURMET ,
2022-03-04 19:57:58 +02:00
}
end
function Public . assign_class ( player_index , class , self_assigned )
local memory = Memory.get_crew_memory ( )
2022-03-13 20:19:59 +02:00
local player = game.players [ player_index ]
2022-03-04 19:57:58 +02:00
if not memory.classes_table then memory.classes_table = { } end
2022-03-13 20:19:59 +02:00
if memory.classes_table [ player_index ] == class then
Common.notify_player_error ( player , ' Class error: You \' re already a ' .. Public.display_form [ class ] .. ' . ' )
return false
end
2022-03-04 19:57:58 +02:00
if Utils.contains ( memory.spare_classes , class ) then -- verify that one is spare
2022-03-13 20:19:59 +02:00
2022-03-14 14:44:30 +02:00
Public.try_renounce_class ( player , false )
2022-03-19 23:20:55 +02:00
2022-03-04 19:57:58 +02:00
memory.classes_table [ player_index ] = class
2022-03-19 23:20:55 +02:00
2022-03-04 19:57:58 +02:00
local force = memory.force
if force and force.valid then
local message
if self_assigned then
message = ' %s took the spare class %s. ([font=scenario-message-dialog]%s[/font]) '
2022-03-13 20:19:59 +02:00
Common.notify_force_light ( force , string.format ( message , player.name , Public.display_form [ memory.classes_table [ player_index ] ] , Public.explanation [ memory.classes_table [ player_index ] ] ) )
2022-03-04 19:57:58 +02:00
else
message = ' A spare %s class was given to %s. [font=scenario-message-dialog](%s)[/font] '
2022-03-13 20:19:59 +02:00
Common.notify_force_light ( force , string.format ( message , Public.display_form [ memory.classes_table [ player_index ] ] , player.name , Public.explanation [ memory.classes_table [ player_index ] ] ) )
2022-03-04 19:57:58 +02:00
end
end
2022-03-19 23:20:55 +02:00
2022-03-04 19:57:58 +02:00
memory.spare_classes = Utils.ordered_table_with_single_value_removed ( memory.spare_classes , class )
2022-03-13 20:19:59 +02:00
return true
else
Common.notify_player_error ( player , ' Class error: No spare class of that type is available. ' )
return false
2022-03-04 19:57:58 +02:00
end
end
2022-03-14 14:44:30 +02:00
function Public . try_renounce_class ( player , whisper_failure_message , override_message )
2022-03-04 19:57:58 +02:00
local memory = Memory.get_crew_memory ( )
local force = memory.force
2022-03-13 20:19:59 +02:00
if force and force.valid and player and player.index then
if memory.classes_table and memory.classes_table [ player.index ] then
2022-03-04 19:57:58 +02:00
if force and force.valid then
if override_message then
Common.notify_force_light ( force , string.format ( override_message , Public.display_form [ memory.classes_table [ player.index ] ] ) )
else
2022-03-09 01:36:03 +02:00
Common.notify_force_light ( force , string.format ( ' %s gave up %s. ' , player.name , Public.display_form [ memory.classes_table [ player.index ] ] ) ) --shorter for less spam
-- Common.notify_force_light(force,string.format('%s gave up the class %s.', player.name, Public.display_form[memory.classes_table[player.index]]))
2022-03-04 19:57:58 +02:00
end
end
memory.spare_classes [ # memory.spare_classes + 1 ] = memory.classes_table [ player.index ]
memory.classes_table [ player.index ] = nil
2022-03-14 14:44:30 +02:00
elseif whisper_failure_message then
2022-03-13 20:19:59 +02:00
Common.notify_player_error ( player , ' Class error: You don \' t have any class to give up. ' )
2022-03-04 19:57:58 +02:00
end
end
end
function Public . generate_class_for_sale ( )
local memory = Memory.get_crew_memory ( )
2022-03-19 23:20:55 +02:00
-- if #memory.available_classes_pool == 0 then
-- -- memory.available_classes_pool = Public.initial_class_pool() --reset to initial state
-- -- turned off as this makes too many classes
-- end
2022-03-09 01:36:03 +02:00
local class
if # memory.available_classes_pool > 0 then
class = memory.available_classes_pool [ Math.random ( # memory.available_classes_pool ) ]
2022-03-07 22:15:47 +02:00
end
2022-03-04 19:57:58 +02:00
2022-03-07 22:15:47 +02:00
return class
end
function Public . class_ore_grant ( player , how_much , disable_scaling )
local count
if disable_scaling then
count = Math.ceil ( how_much )
else
count = Math.ceil ( how_much * Balance.class_resource_scale ( ) )
end
2022-03-13 03:44:32 +02:00
if Math.random ( 4 ) == 1 then
2022-03-07 22:15:47 +02:00
Common.flying_text_small ( player.surface , player.position , ' [color=0.85,0.58,0.37]+ ' .. count .. ' [/color] ' )
2022-03-09 01:36:03 +02:00
Common.give_items_to_crew { { name = ' copper-ore ' , count = count } }
2022-03-04 19:57:58 +02:00
else
2022-03-07 22:15:47 +02:00
Common.flying_text_small ( player.surface , player.position , ' [color=0.7,0.8,0.8]+ ' .. count .. ' [/color] ' )
2022-03-09 01:36:03 +02:00
Common.give_items_to_crew { { name = ' iron-ore ' , count = count } }
2022-03-04 19:57:58 +02:00
end
end
2022-03-07 22:15:47 +02:00
local function class_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 ]
2022-03-14 14:44:30 +02:00
if class == Public.enum . GOURMET then
2022-03-07 22:15:47 +02:00
local tile = player.surface . get_tile ( player.position )
if tile.valid then
local multiplier = 0
if tile.name == CoreData.world_concrete_tile then
multiplier = 1.5
elseif tile.name == ' cyan-refined-concrete ' then
2022-03-09 01:36:03 +02:00
multiplier = 1.6
2022-03-07 22:15:47 +02:00
elseif tile.name == CoreData.walkway_tile then
multiplier = 1
elseif tile.name == ' orange-refined-concrete ' then
2022-03-09 01:36:03 +02:00
multiplier = 0.8
elseif tile.name == CoreData.enemy_landing_tile then
multiplier = 0.33
elseif tile.name == CoreData.static_boat_floor then
multiplier = 0.1
2022-03-07 22:15:47 +02:00
end
if multiplier > 0 then
2022-03-09 01:36:03 +02:00
local timescale = 60 * 30 * Math.max ( ( Balance.game_slowness_scale ( ) ) ^ ( 2 / 3 ) , 0.8 )
2022-03-07 22:15:47 +02:00
if memory.gourmet_recency_tick then
multiplier = multiplier * Math.max ( 0.2 , Math.min ( 5 , ( 1 / 5 ) ^ ( ( memory.gourmet_recency_tick - game.tick ) / ( 60 * 300 ) ) ) )
2022-03-09 01:36:03 +02:00
memory.gourmet_recency_tick = Math.max ( memory.gourmet_recency_tick , game.tick - timescale * 10 ) + timescale
2022-03-07 22:15:47 +02:00
else
multiplier = multiplier * 5
2022-03-09 01:36:03 +02:00
memory.gourmet_recency_tick = game.tick - timescale * 10 + timescale
2022-03-07 22:15:47 +02:00
end
2022-03-09 01:36:03 +02:00
Public.class_ore_grant ( player , 10 * multiplier , true )
2022-03-07 22:15:47 +02:00
end
end
end
end
end
local event = require ' utils.event '
event.add ( defines.events . on_player_used_capsule , class_on_player_used_capsule )
2021-10-13 10:21:53 +02:00
return Public