1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-10 00:43:27 +02:00
ComfyFactorio/maps/pirates/roles/classes.lua

285 lines
9.6 KiB
Lua
Raw Normal View History

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