mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-10 00:43:27 +02:00
commit
cfad373816
@ -112,7 +112,7 @@ require 'utils.freeplay'
|
||||
--require 'maps.chronosphere.main'
|
||||
|
||||
--![[Adventure as a crew of pirates]]--
|
||||
require 'maps.pirates.main'
|
||||
--require 'maps.pirates.main'
|
||||
|
||||
--![[Launch rockets in increasingly harder getting worlds.]]--
|
||||
--require 'maps.journey.main'
|
||||
|
@ -210,42 +210,63 @@ role_officer_description=Assigned by the captain, officers can use the Captain's
|
||||
role_captain=Captain
|
||||
role_captain_description=Has executive power to undock the ship, purchase items, and various other special actions. When the game assigns a captain, it gives priority to those who have been playing the longest as a non-captain.
|
||||
|
||||
class_obtainable=Class is obtainable.
|
||||
class_unobtainable=Class was disabled and is unobtainable.
|
||||
|
||||
class_deckhand=Deckhand
|
||||
class_deckhand_explanation=They move faster and generate ore for the cabin whilst onboard above deck.
|
||||
class_deckhand_explanation_advanced=They move __1__% times faster and generate ore (with current crew size +__2__ every __3__ seconds) for the cabin whilst onboard above deck.
|
||||
class_fisherman=Fisherman
|
||||
class_fisherman_explanation=They fish at greater distance.
|
||||
class_fisherman_explanation_advanced=They fish (as well as reach objects as side effect) at greater distance (__1__ extra tile range).
|
||||
class_scout=Scout
|
||||
class_scout_explanation=They are faster, but frail and deal less damage.
|
||||
class_scout_explanation_advanced=They move __1__% times faster, but receive __2__% more damage and deal __3__% less damage.
|
||||
class_samurai=Samurai
|
||||
class_samurai_explanation=They are tough, and *with no weapon equipped* fight well by melee, but poorly otherwise.
|
||||
class_samurai_explanation_advanced=They receive __1__% less damage, and with no weapon equipped do extra __2__ damage in melee (scales with 'physical projectile damage' research bonuses), but deal __3__% less damage otherwise.
|
||||
class_merchant=Merchant
|
||||
class_merchant_explanation=They generate 50 doubloons per league.
|
||||
class_merchant_explanation_advanced=They generate 50 doubloons per league.
|
||||
class_shoresman=Shoresman
|
||||
class_shoresman_explanation=They move slightly faster and generate ore for the cabin whilst offboard.
|
||||
class_shoresman_explanation_advanced=They move __1__% times faster and generate ore (with current crew size +__2__ every __3__ seconds) for the cabin whilst offboard.
|
||||
class_boatswain=Boatswain
|
||||
class_boatswain_explanation=They move faster and generate ore for the cabin whilst below deck.
|
||||
class_boatswain_explanation_advanced=They move __1__% times faster and generate ore (with current crew size +__2__ every __3__ seconds) for the cabin whilst below deck.
|
||||
class_prospector=Prospector
|
||||
class_prospector_explanation=They find more resources when handmining.
|
||||
class_prospector_explanation_advanced=They find more resources when handmining.
|
||||
class_lumberjack=Lumberjack
|
||||
class_lumberjack_explanation=They find more resources when chopping trees.
|
||||
class_lumberjack_explanation_advanced=They find ores and more coins when chopping trees.
|
||||
class_master_angler=Master Angler
|
||||
class_master_angler_explanation=They fish at much greater distance, and catch more.
|
||||
class_master_angler_explanation_advanced=They fish at much greater distance (__1__ extra tile range), and catch more (+__2__ fish and +__3__ coins).
|
||||
class_wood_lord=Lord of the Woods
|
||||
class_wood_lord_explanation=They find many more resources when chopping trees.
|
||||
class_wood_lord_explanation_advanced=They find many more resources when chopping trees.
|
||||
class_chief_excavator=Chief Excavator
|
||||
class_chief_excavator_explanation=They find many more resources when handmining.
|
||||
class_chief_excavator_explanation_advanced=They find many more resources when handmining.
|
||||
class_hatamoto=Hatamoto
|
||||
class_hatamoto_explanation=They are very tough, and *with no weapon equipped* fight well by melee, but poorly otherwise.
|
||||
class_hatamoto_explanation_advanced=They receive __1__% less damage, and with no weapon equipped do extra __2__ damage in melee (scales with 'physical projectile damage' research bonuses), but deal __3__% less damage otherwise.
|
||||
class_iron_leg=Iron Leg
|
||||
class_iron_leg_explanation=They are very resistant to damage when carrying 3000 iron ore.
|
||||
class_iron_leg_explanation_advanced=They receive __1__% less damage when carrying at least __2__ iron ore.
|
||||
class_quartermaster=Quartermaster
|
||||
class_quartermaster_explanation=Nearby crewmates get +10% physical attack and generate ore for the cabin.
|
||||
class_quartermaster_explanation_advanced=Nearby crewmates (at __1__ tile radius) get +__2__% physical attack and generate ore for the cabin (ore amount depends on nearby crewmate count).
|
||||
class_dredger=Dredger
|
||||
class_dredger_explanation=They find surprising items when they fish.
|
||||
class_dredger_explanation_advanced=They inherit the previous class bonuses and find surprising items when they fish.
|
||||
class_smoldering=Smoldering
|
||||
class_smoldering_explanation=They periodically convert wood into coal, if they have less than 50 coal.
|
||||
class_smoldering_explanation_advanced=They periodically convert wood into coal, if they have less than 50 coal.
|
||||
class_gourmet=Gourmet
|
||||
class_gourmet_explanation=They generate ore for the cabin by eating fish in fancy locations.
|
||||
class_gourmet_explanation_advanced=They generate ore for the cabin by eating fish in fancy locations.
|
||||
|
||||
|
||||
class_explanation=__1__: __2__
|
||||
|
@ -278,20 +278,22 @@ local function damage_to_players_changes(event)
|
||||
|
||||
local damage_multiplier = 1
|
||||
|
||||
if event.damage_type.name == 'poison' then --make all poison damage stronger against players
|
||||
damage_multiplier = damage_multiplier * 1.85
|
||||
--game.print('on damage info: {name: ' .. event.damage_type.name .. ', object_name: ' .. event.damage_type.object_name .. '}')
|
||||
|
||||
if event.damage_type.name == 'poison' then --make all poison damage stronger against players and enemies
|
||||
damage_multiplier = damage_multiplier * Balance.poison_damage_multiplier
|
||||
else
|
||||
if class and class == Classes.enum.SCOUT then
|
||||
damage_multiplier = damage_multiplier * 1.25
|
||||
damage_multiplier = damage_multiplier * Balance.scout_damage_taken_multiplier
|
||||
-- elseif class and class == Classes.enum.MERCHANT then
|
||||
-- damage_multiplier = damage_multiplier * 1.10
|
||||
elseif class and class == Classes.enum.SAMURAI then
|
||||
damage_multiplier = damage_multiplier * (1 - Balance.samurai_resistance)
|
||||
elseif class and class == Classes.enum.HATAMOTO then
|
||||
damage_multiplier = damage_multiplier * (1 - Balance.hatamoto_resistance)
|
||||
elseif class and class == Classes.enum.IRON_LEG then
|
||||
damage_multiplier = damage_multiplier * Balance.samurai_damage_taken_multiplier
|
||||
elseif class and class == Classes.enum.HATAMOTO then --lethal damage needs to be unaffected
|
||||
damage_multiplier = damage_multiplier * Balance.hatamoto_damage_taken_multiplier
|
||||
elseif class and class == Classes.enum.IRON_LEG then --lethal damage needs to be unaffected
|
||||
if memory.class_auxiliary_data[player_index] and memory.class_auxiliary_data[player_index].iron_leg_active then
|
||||
damage_multiplier = damage_multiplier * (1 - Balance.iron_leg_resistance)
|
||||
damage_multiplier = damage_multiplier * Balance.iron_leg_damage_taken_multiplier
|
||||
end
|
||||
-- else
|
||||
-- damage_multiplier = damage_multiplier * (1 + Balance.bonus_damage_to_humans())
|
||||
@ -308,6 +310,24 @@ local function damage_to_players_changes(event)
|
||||
elseif damage_multiplier < 1 and event.final_health > 0 then --lethal damage needs to be unaffected, else they never die
|
||||
event.entity.health = event.entity.health + event.final_damage_amount * (1 - damage_multiplier)
|
||||
end
|
||||
|
||||
|
||||
-- deal with damage reduction on lethal damage for players
|
||||
local player = game.players[player_index]
|
||||
if not (player and player.valid and player.character and player.character.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
local global_memory = Memory.get_global_memory()
|
||||
|
||||
if damage_multiplier < 1 and event.final_health <= 0 then
|
||||
local damage_dealt = event.final_damage_amount * damage_multiplier
|
||||
if damage_dealt < global_memory.last_players_health[player_index] then
|
||||
event.entity.health = global_memory.last_players_health[player_index] - damage_dealt
|
||||
end
|
||||
end
|
||||
|
||||
global_memory.last_players_health[player_index] = event.entity.health
|
||||
end
|
||||
|
||||
|
||||
@ -351,7 +371,7 @@ local function damage_dealt_by_players_changes(event)
|
||||
local class = memory.classes_table and memory.classes_table[player_index]
|
||||
|
||||
if class and class == Classes.enum.SCOUT and event.final_health > 0 then --lethal damage must be unaffected
|
||||
event.entity.health = event.entity.health + 0.4 * event.final_damage_amount
|
||||
event.entity.health = event.entity.health + (1 - Balance.scout_damage_dealt_multiplier) * event.final_damage_amount
|
||||
elseif class and (class == Classes.enum.SAMURAI or class == Classes.enum.HATAMOTO) then
|
||||
local samurai = memory.classes_table[player_index] == Classes.enum.SAMURAI
|
||||
local hatamoto = memory.classes_table[player_index] == Classes.enum.HATAMOTO
|
||||
@ -367,19 +387,23 @@ local function damage_dealt_by_players_changes(event)
|
||||
|
||||
local big_number = 1000
|
||||
|
||||
local extra_physical_damage_from_research_multiplier = 1 + memory.force.get_ammo_damage_modifier('bullet')
|
||||
|
||||
if melee and event.final_health > 0 then
|
||||
if physical then
|
||||
if samurai then
|
||||
extra_damage_to_deal = 30
|
||||
extra_damage_to_deal = Balance.samurai_damage_dealt_with_melee_multiplier * extra_physical_damage_from_research_multiplier
|
||||
elseif hatamoto then
|
||||
extra_damage_to_deal = 50
|
||||
extra_damage_to_deal = Balance.hatamoto_damage_dealt_with_melee_multiplier * extra_physical_damage_from_research_multiplier
|
||||
end
|
||||
elseif acid then --this hacky stuff is to implement repeated spillover splash damage, whilst getting around the fact that if ovekill damage takes something to zero health, we can't tell in that event how much double-overkill damage should be dealt by reading off its HP. This code assumes that characters only deal acid damage via this function.
|
||||
extra_damage_to_deal = event.original_damage_amount * big_number
|
||||
end
|
||||
elseif (not melee) and event.final_health > 0 then
|
||||
if samurai or hatamoto then
|
||||
event.entity.health = event.entity.health + 0.25 * event.final_damage_amount
|
||||
if samurai then
|
||||
event.entity.health = event.entity.health + (1 - Balance.samurai_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
|
||||
elseif hatamoto then
|
||||
event.entity.health = event.entity.health + (1 - Balance.hatamoto_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
|
||||
end
|
||||
end
|
||||
|
||||
@ -400,13 +424,13 @@ local function damage_dealt_by_players_changes(event)
|
||||
if physical then
|
||||
|
||||
-- QUARTERMASTER BUFFS
|
||||
local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = Common.quartermaster_range, type = {'character'}}
|
||||
local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = Balance.quartermaster_range, type = {'character'}}
|
||||
|
||||
for _, p2 in pairs(nearby_players) do
|
||||
if p2.player and p2.player.valid then
|
||||
local p2_index = p2.player.index
|
||||
if event.entity.valid and player_index ~= p2_index and memory.classes_table[p2_index] and memory.classes_table[p2_index] == Classes.enum.QUARTERMASTER then
|
||||
event.entity.damage(0.1 * event.final_damage_amount, character.force, 'impact', character) --triggers this function again, but not physical this time
|
||||
event.entity.damage(Balance.quartermaster_bonus_physical_damage * event.final_damage_amount, character.force, 'impact', character) --triggers this function again, but not physical this time
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -660,10 +684,6 @@ end
|
||||
-- -- end
|
||||
-- end
|
||||
|
||||
|
||||
Public.every_nth_tree_gives_coins = 6
|
||||
|
||||
|
||||
local function event_on_player_mined_entity(event)
|
||||
if not event.player_index then return end
|
||||
local player = game.players[event.player_index]
|
||||
@ -739,7 +759,7 @@ local function event_on_player_mined_entity(event)
|
||||
-- end
|
||||
else
|
||||
give[#give + 1] = {name = 'wood', count = amount}
|
||||
if Math.random(Public.every_nth_tree_gives_coins) == 1 then --tuned
|
||||
if Math.random(Balance.every_nth_tree_gives_coins) == 1 then --tuned
|
||||
local a = 5
|
||||
give[#give + 1] = {name = 'coin', count = a}
|
||||
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
|
||||
@ -756,13 +776,13 @@ local function event_on_player_mined_entity(event)
|
||||
|
||||
|
||||
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 = 4}, {name = 'coin', count = 10}}, entity.position)
|
||||
Common.give(player, {{name = 'raw-fish', count = Balance.base_caught_fish_amount + Balance.master_angler_fish_bonus}, {name = 'coin', count = Balance.master_angler_coin_bonus}}, entity.position)
|
||||
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.DREDGER then
|
||||
local to_give = {{name = 'raw-fish', count = 4}}
|
||||
local to_give = {{name = 'raw-fish', count = Balance.base_caught_fish_amount + Balance.dredger_fish_bonus}}
|
||||
to_give[#to_give + 1] = Loot.dredger_loot()[1]
|
||||
Common.give(player, to_give, entity.position)
|
||||
else
|
||||
Common.give(player, {{name = 'raw-fish', count = 3}}, entity.position)
|
||||
Common.give(player, {{name = 'raw-fish', count = Balance.base_caught_fish_amount}}, entity.position)
|
||||
end
|
||||
|
||||
event.buffer.clear()
|
||||
@ -1263,6 +1283,8 @@ local function event_on_player_joined_game(event)
|
||||
Gui.info.toggle_window(player)
|
||||
end
|
||||
|
||||
global_memory.last_players_health[event.player_index] = player.character.health
|
||||
|
||||
-- player.teleport(surface.find_non_colliding_position('character', spawnpoint, 32, 0.5), surface)
|
||||
-- -- for item, amount in pairs(Balance.starting_items_player) do
|
||||
-- -- player.insert({name = item, count = amount})
|
||||
@ -1332,6 +1354,8 @@ local function event_on_pre_player_left_game(event)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
global_memory.last_players_health[event.player_index] = nil
|
||||
end
|
||||
|
||||
|
||||
@ -1795,6 +1819,9 @@ local function event_on_player_respawned(event)
|
||||
|
||||
if player.character and player.character.valid then
|
||||
Task.set_timeout_in_ticks(360, boost_movement_speed_on_respawn, {player = player, crew_id = crew_id})
|
||||
|
||||
local global_memory = Memory.get_global_memory()
|
||||
global_memory.last_players_health[event.player_index] = player.character.health
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -11,12 +11,62 @@ local _inspect = require 'utils.inspect'.inspect
|
||||
|
||||
-- this file is an API to all the balance tuning knobs
|
||||
|
||||
-- damage_taken_multiplier:
|
||||
-- if multiplier > 1: entity takes more damage
|
||||
-- if multiplier < 1: entity takes less damage (has damage reduction)
|
||||
|
||||
-- damage_dealt_multiplier:
|
||||
-- if multiplier > 1: entity deals more damage
|
||||
-- if multiplier < 1: entity deals less damage
|
||||
|
||||
-- extra_speed:
|
||||
-- if multiplier > 1: entity moves faster
|
||||
-- if multiplier < 1: entity moves slower
|
||||
-- NOTE: when some extra speed modifiers stack, they stack multiplicatively
|
||||
|
||||
Public.base_extra_character_speed = 1.44
|
||||
Public.respawn_speed_boost = 1.75
|
||||
|
||||
Public.base_extra_character_speed = 0.20
|
||||
Public.cannon_starting_hp = 2000
|
||||
Public.cannon_resistance_factor = 2.5
|
||||
Public.technology_price_multiplier = 1
|
||||
Public.rocket_launch_coin_reward = 5000
|
||||
|
||||
Public.base_caught_fish_amount = 3
|
||||
Public.class_reward_tick_rate_in_seconds = 7
|
||||
Public.poison_damage_multiplier = 1.85
|
||||
Public.every_nth_tree_gives_coins = 6
|
||||
|
||||
Public.samurai_damage_taken_multiplier = 0.26
|
||||
Public.samurai_damage_dealt_when_not_melee_multiplier = 0.75
|
||||
Public.samurai_damage_dealt_with_melee_multiplier = 25
|
||||
Public.hatamoto_damage_taken_multiplier = 0.16
|
||||
Public.hatamoto_damage_dealt_when_not_melee_multiplier = 0.75
|
||||
Public.hatamoto_damage_dealt_with_melee_multiplier = 45
|
||||
Public.iron_leg_damage_taken_multiplier = 0.18
|
||||
Public.iron_leg_iron_ore_required = 3000
|
||||
Public.deckhand_extra_speed = 1.25
|
||||
Public.deckhand_ore_grant_multiplier = 2
|
||||
Public.deckhand_ore_scaling_enabled = true
|
||||
Public.boatswain_extra_speed = 1.25
|
||||
Public.boatswain_ore_grant_multiplier = 4
|
||||
Public.boatswain_ore_scaling_enabled = true
|
||||
Public.shoresman_extra_speed = 1.1
|
||||
Public.shoresman_ore_grant_multiplier = 2
|
||||
Public.shoresman_ore_scaling_enabled = true
|
||||
Public.quartermaster_range = 19
|
||||
Public.quartermaster_bonus_physical_damage = 0.1
|
||||
Public.quartermaster_ore_scaling_enabled = false
|
||||
Public.scout_extra_speed = 1.3
|
||||
Public.scout_damage_taken_multiplier = 1.25
|
||||
Public.scout_damage_dealt_multiplier = 0.6
|
||||
Public.fisherman_reach_bonus = 10
|
||||
Public.master_angler_reach_bonus = 16
|
||||
Public.master_angler_fish_bonus = 1
|
||||
Public.master_angler_coin_bonus = 10
|
||||
Public.dredger_reach_bonus = 16
|
||||
Public.dredger_fish_bonus = 1
|
||||
Public.gourmet_ore_scaling_enabled = false
|
||||
|
||||
function Public.starting_boatEEIpower_production_MW()
|
||||
-- return 3 * Math.sloped(Common.capacity_scale(), 1/2) / 2 --/2 as we have 2
|
||||
@ -44,8 +94,6 @@ function Public.cost_to_leave_multiplier()
|
||||
return Math.sloped(Common.difficulty_scale(), 8/10)
|
||||
end
|
||||
|
||||
Public.rocket_launch_coin_reward = 5000
|
||||
|
||||
function Public.crew_scale()
|
||||
local ret = Common.activecrewcount()/10
|
||||
if ret == 0 then ret = 1/10 end --if all players are afk
|
||||
@ -301,10 +349,6 @@ function Public.class_resource_scale()
|
||||
return 1 / (Public.crew_scale()^(2/5)) --already helped by longer timescales
|
||||
end
|
||||
|
||||
Public.samurai_resistance = 0.74
|
||||
Public.hatamoto_resistance = 0.84
|
||||
Public.iron_leg_resistance = 0.82
|
||||
|
||||
function Public.biter_base_density_scale()
|
||||
local p = Public.crew_scale()
|
||||
if p >= 1 then
|
||||
|
@ -229,7 +229,7 @@ function(cmd)
|
||||
if not Common.validate_player(player) then return end
|
||||
|
||||
if param and param ~= 'nil' then
|
||||
local string = Roles.get_class_print_string(param)
|
||||
local string = Roles.get_class_print_string(param, false)
|
||||
if string then
|
||||
Common.notify_player_expected(player, {'', 'Class definition for ', string})
|
||||
else
|
||||
@ -240,6 +240,27 @@ function(cmd)
|
||||
end
|
||||
end)
|
||||
|
||||
commands.add_command(
|
||||
'classinfofull',
|
||||
'{classname} returns detailed definition of the named class.',
|
||||
function(cmd)
|
||||
cmd_set_memory(cmd)
|
||||
local param = tostring(cmd.parameter)
|
||||
local player = game.players[cmd.player_index]
|
||||
if not Common.validate_player(player) then return end
|
||||
|
||||
if param and param ~= 'nil' then
|
||||
local string = Roles.get_class_print_string(param, true)
|
||||
if string then
|
||||
Common.notify_player_expected(player, {'', 'Class definition for ', string})
|
||||
else
|
||||
Common.notify_player_error(player, 'Command error: Class ' .. param .. ' not found.')
|
||||
end
|
||||
else
|
||||
Common.notify_player_expected(player, '/classinfofull {classname} returns detailed definition of the named class.')
|
||||
end
|
||||
end)
|
||||
|
||||
commands.add_command(
|
||||
'take',
|
||||
'{classname} takes a spare class with the given name for yourself.',
|
||||
@ -1025,4 +1046,16 @@ if _DEBUG then
|
||||
Server.to_discord_embed_raw(CoreData.comfy_emojis.monkas)
|
||||
end
|
||||
end)
|
||||
|
||||
commands.add_command(
|
||||
'piratux_test',
|
||||
'is a dev command of piratux.',
|
||||
function(cmd)
|
||||
local param = tostring(cmd.parameter)
|
||||
if check_admin(cmd) then
|
||||
local player = game.players[cmd.player_index]
|
||||
|
||||
player.print('speed: ' .. player.character.speed .. 'effective_speed: ' .. player.character.effective_speed)
|
||||
end
|
||||
end)
|
||||
end
|
@ -37,7 +37,6 @@ Public.deepwater_distance_from_leftmost_shore = 32
|
||||
Public.lobby_spawnpoint = {x = -72, y = -8}
|
||||
Public.structure_ensure_chunk_radius = 2
|
||||
|
||||
Public.quartermaster_range = 19
|
||||
Public.allow_barreling_off_ship = true
|
||||
|
||||
Public.coin_tax_percentage = 10
|
||||
|
@ -839,7 +839,7 @@ function Public.reset_crew_and_enemy_force(id)
|
||||
crew_force.manual_mining_speed_modifier = 3
|
||||
crew_force.character_inventory_slots_bonus = 0
|
||||
-- crew_force.character_inventory_slots_bonus = 10
|
||||
crew_force.character_running_speed_modifier = Balance.base_extra_character_speed
|
||||
-- crew_force.character_running_speed_modifier = Balance.base_extra_character_speed
|
||||
crew_force.laboratory_productivity_bonus = 0
|
||||
crew_force.ghost_time_to_live = 12 * 60 * 60
|
||||
|
||||
|
@ -113,7 +113,7 @@ local function on_init()
|
||||
Surfaces.Lobby.create_starting_dock_surface()
|
||||
local lobby = game.surfaces[CoreData.lobby_surface_name]
|
||||
game.forces.player.set_spawn_position(Common.lobby_spawnpoint, lobby)
|
||||
game.forces.player.character_running_speed_modifier = Balance.base_extra_character_speed
|
||||
-- game.forces.player.character_running_speed_modifier = Balance.base_extra_character_speed
|
||||
|
||||
game.create_force('environment')
|
||||
for id = 1, 3, 1 do
|
||||
@ -248,8 +248,8 @@ local function crew_tick()
|
||||
end
|
||||
|
||||
|
||||
if tick % 420 == 0 then
|
||||
ClassPiratesApiOnTick.class_rewards_tick(420)
|
||||
if tick % (60 * Balance.class_reward_tick_rate_in_seconds) == 0 then
|
||||
ClassPiratesApiOnTick.class_rewards_tick(60 * Balance.class_reward_tick_rate_in_seconds)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -37,6 +37,8 @@ function Public.global_reset_memory()
|
||||
|
||||
pirates_global_memory.global_delayed_tasks = {}
|
||||
pirates_global_memory.global_buffered_tasks = {}
|
||||
|
||||
pirates_global_memory.last_players_health = {} --used to make damage reduction work somewhat properly
|
||||
end
|
||||
|
||||
|
||||
|
@ -70,6 +70,65 @@ function Public.explanation(class)
|
||||
return {'pirates.class_' .. class .. '_explanation'}
|
||||
end
|
||||
|
||||
function Public.explanation_advanced(class)
|
||||
local explanation = 'pirates.class_' .. class .. '_explanation_advanced'
|
||||
local full_explanation = {}
|
||||
|
||||
if class == enum.DECKHAND then
|
||||
local extra_speed = Public.percentage_points_difference_from_100_percent(Balance.deckhand_extra_speed)
|
||||
local ore_amount = Public.ore_grant_amount(Balance.deckhand_ore_grant_multiplier, Balance.deckhand_ore_scaling_enabled)
|
||||
local tick_rate = Balance.class_reward_tick_rate_in_seconds
|
||||
full_explanation = {'', {explanation, extra_speed, ore_amount, tick_rate}}
|
||||
elseif class == enum.BOATSWAIN then
|
||||
local extra_speed = Public.percentage_points_difference_from_100_percent(Balance.boatswain_extra_speed)
|
||||
local ore_amount = Public.ore_grant_amount(Balance.boatswain_ore_grant_multiplier, Balance.boatswain_ore_scaling_enabled)
|
||||
local tick_rate = Balance.class_reward_tick_rate_in_seconds
|
||||
full_explanation = {'', {explanation, extra_speed, ore_amount, tick_rate}}
|
||||
elseif class == enum.SHORESMAN then
|
||||
local extra_speed = Public.percentage_points_difference_from_100_percent(Balance.shoresman_extra_speed)
|
||||
local ore_amount = Public.ore_grant_amount(Balance.shoresman_ore_grant_multiplier, Balance.shoresman_ore_scaling_enabled)
|
||||
local tick_rate = Balance.class_reward_tick_rate_in_seconds
|
||||
full_explanation = {'', {explanation, extra_speed, ore_amount, tick_rate}}
|
||||
elseif class == enum.QUARTERMASTER then
|
||||
local range = Balance.quartermaster_range
|
||||
local extra_physical = Public.percentage_points_difference_from_100_percent(Balance.quartermaster_bonus_physical_damage)
|
||||
full_explanation = {'', {explanation, range, extra_physical}}
|
||||
elseif class == enum.FISHERMAN then
|
||||
local extra_range = Balance.fisherman_reach_bonus
|
||||
full_explanation = {'', {explanation, extra_range}}
|
||||
elseif class == enum.MASTER_ANGLER then
|
||||
local extra_range = Balance.master_angler_reach_bonus
|
||||
local extra_fish = Balance.master_angler_fish_bonus
|
||||
local extra_coins = Balance.master_angler_coin_bonus
|
||||
full_explanation = {'', {explanation, extra_range, extra_fish, extra_coins}}
|
||||
elseif class == enum.SCOUT then
|
||||
local extra_speed = Public.percentage_points_difference_from_100_percent(Balance.scout_extra_speed)
|
||||
local received_damage = Public.percentage_points_difference_from_100_percent(Balance.scout_damage_taken_multiplier)
|
||||
local dealt_damage = Public.percentage_points_difference_from_100_percent(Balance.scout_damage_dealt_multiplier)
|
||||
full_explanation = {'', {explanation, extra_speed, received_damage, dealt_damage}}
|
||||
elseif class == enum.SAMURAI then
|
||||
local received_damage = Public.percentage_points_difference_from_100_percent(Balance.samurai_damage_taken_multiplier)
|
||||
local melee_damage = Balance.samurai_damage_dealt_with_melee_multiplier
|
||||
local non_melee_damage = Public.percentage_points_difference_from_100_percent(Balance.samurai_damage_dealt_when_not_melee_multiplier)
|
||||
full_explanation = {'', {explanation, received_damage, melee_damage, non_melee_damage}}
|
||||
elseif class == enum.HATAMOTO then
|
||||
local received_damage = Public.percentage_points_difference_from_100_percent(Balance.hatamoto_damage_taken_multiplier)
|
||||
local melee_damage = Balance.hatamoto_damage_dealt_with_melee_multiplier
|
||||
local non_melee_damage = Public.percentage_points_difference_from_100_percent(Balance.hatamoto_damage_dealt_when_not_melee_multiplier)
|
||||
full_explanation = {'', {explanation, received_damage, melee_damage, non_melee_damage}}
|
||||
elseif class == enum.IRON_LEG then
|
||||
local received_damage = Public.percentage_points_difference_from_100_percent(Balance.iron_leg_damage_taken_multiplier)
|
||||
local iron_ore_required = Balance.iron_leg_iron_ore_required
|
||||
full_explanation = {'', {explanation, received_damage, iron_ore_required}}
|
||||
else
|
||||
full_explanation = {'', {explanation}}
|
||||
end
|
||||
|
||||
full_explanation[#full_explanation + 1] = Public.class_is_obtainable(class) and {'', ' ', {'pirates.class_obtainable'}} or {'', ' ', {'pirates.class_unobtainable'}}
|
||||
|
||||
return full_explanation
|
||||
end
|
||||
|
||||
-- Public.display_form = {
|
||||
-- [enum.DECKHAND] = {'pirates.class_deckhand'},
|
||||
-- }
|
||||
@ -78,6 +137,17 @@ end
|
||||
-- }
|
||||
|
||||
|
||||
-- returns by how much % result changes when you multiply it by multiplier
|
||||
-- for example consider these multiplier cases {0.6, 1.2}:
|
||||
-- number * 0.6 -> result decreased by 40%
|
||||
-- number * 1.2 -> result increased by 20%
|
||||
function Public.percentage_points_difference_from_100_percent(multiplier)
|
||||
if(multiplier < 1) then
|
||||
return (1 - multiplier) * 100
|
||||
else
|
||||
return (multiplier - 1) * 100
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Public.class_unlocks = {
|
||||
@ -116,6 +186,24 @@ function Public.initial_class_pool()
|
||||
}
|
||||
end
|
||||
|
||||
function Public.class_is_obtainable(class)
|
||||
local obtainable_class_pool = Public.initial_class_pool()
|
||||
|
||||
for _, unlocked_class_list in pairs(Public.class_unlocks) do
|
||||
for __, unlocked_class in ipairs(unlocked_class_list) do
|
||||
obtainable_class_pool[#obtainable_class_pool + 1] = unlocked_class
|
||||
end
|
||||
end
|
||||
|
||||
for _, unlockable_class in ipairs(obtainable_class_pool) do
|
||||
if unlockable_class == class then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function Public.assign_class(player_index, class, self_assigned)
|
||||
local memory = Memory.get_crew_memory()
|
||||
@ -191,13 +279,9 @@ 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
|
||||
function Public.class_ore_grant(player, how_much, enable_scaling)
|
||||
local count = ore_grant_amount(how_much, enable_scaling)
|
||||
|
||||
if Math.random(4) == 1 then
|
||||
Common.flying_text_small(player.surface, player.position, '[color=0.85,0.58,0.37]+' .. count .. '[/color]')
|
||||
Common.give_items_to_crew{{name = 'copper-ore', count = count}}
|
||||
@ -207,6 +291,13 @@ function Public.class_ore_grant(player, how_much, disable_scaling)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.ore_grant_amount(how_much, enable_scaling)
|
||||
if enable_scaling then
|
||||
return Math.ceil(how_much * Balance.class_resource_scale())
|
||||
else
|
||||
return Math.ceil(how_much)
|
||||
end
|
||||
end
|
||||
|
||||
local function class_on_player_used_capsule(event)
|
||||
|
||||
@ -227,6 +318,9 @@ local function class_on_player_used_capsule(event)
|
||||
local item = event.item
|
||||
if not (item and item.name and item.name == 'raw-fish') then return end
|
||||
|
||||
local global_memory = Memory.get_global_memory()
|
||||
global_memory.last_players_health[event.player_index] = player.character.health
|
||||
|
||||
if memory.classes_table and memory.classes_table[player_index] then
|
||||
local class = memory.classes_table[player_index]
|
||||
if class == Public.enum.GOURMET then
|
||||
@ -263,7 +357,7 @@ local function class_on_player_used_capsule(event)
|
||||
multiplier = multiplier * 5
|
||||
memory.gourmet_recency_tick = game.tick - timescale*10 + timescale
|
||||
end
|
||||
Public.class_ore_grant(player, 10 * multiplier, true)
|
||||
Public.class_ore_grant(player, 10 * multiplier, Balance.gourmet_ore_scaling_enabled)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -273,7 +367,7 @@ end
|
||||
function Public.lumberjack_bonus_items(give_table)
|
||||
local memory = Memory.get_crew_memory()
|
||||
|
||||
if Math.random(Public.every_nth_tree_gives_coins) == 1 then
|
||||
if Math.random(Balance.every_nth_tree_gives_coins) == 1 then
|
||||
local a = 12
|
||||
give_table[#give_table + 1] = {name = 'coin', count = a}
|
||||
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
|
||||
|
@ -131,14 +131,21 @@ end
|
||||
-- return str
|
||||
-- end
|
||||
|
||||
function Public.get_class_print_string(class)
|
||||
function Public.get_class_print_string(class, full)
|
||||
|
||||
for _, class2 in pairs(Classes.enum) do
|
||||
if Classes.eng_form[class2]:lower() == class:lower() or class2 == class:lower() then
|
||||
local explanation = nil
|
||||
if full then
|
||||
explanation = Classes.explanation_advanced(class2)
|
||||
else
|
||||
explanation = Classes.explanation(class2)
|
||||
end
|
||||
|
||||
if Classes.class_purchase_requirement[class2] then
|
||||
return {'pirates.class_explanation_upgraded_class', Classes.display_form(class2), Classes.display_form(Classes.class_purchase_requirement[class2]), Classes.explanation(class2)}
|
||||
return {'pirates.class_explanation_upgraded_class', Classes.display_form(class2), Classes.display_form(Classes.class_purchase_requirement[class2]), explanation}
|
||||
else
|
||||
return {'pirates.class_explanation', Classes.display_form(class2), Classes.explanation(class2)}
|
||||
return {'pirates.class_explanation', Classes.display_form(class2), explanation}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
|
||||
|
||||
--luacheck: ignore
|
||||
--luacheck ignores because tickinterval arguments are a code templating choice...
|
||||
|
||||
@ -38,7 +36,7 @@ function Public.class_update_auxiliary_data(tickinterval)
|
||||
local inv = player.character.get_inventory(defines.inventory.character_main)
|
||||
if inv and inv.valid then
|
||||
local count = inv.get_item_count('iron-ore')
|
||||
if count and count >= 3000 then
|
||||
if count and count >= Balance.iron_leg_iron_ore_required then
|
||||
check = true
|
||||
end
|
||||
end
|
||||
@ -105,7 +103,7 @@ function Public.class_renderings(tickinterval)
|
||||
target = player.character,
|
||||
color = CoreData.colors.toughness_rendering,
|
||||
filled = false,
|
||||
radius = Balance.samurai_resistance^2,
|
||||
radius = (1 - Balance.samurai_damage_taken_multiplier)^2,
|
||||
only_in_alt_mode = false,
|
||||
draw_on_ground = true,
|
||||
}
|
||||
@ -117,7 +115,7 @@ function Public.class_renderings(tickinterval)
|
||||
target = player.character,
|
||||
color = CoreData.colors.toughness_rendering,
|
||||
filled = false,
|
||||
radius = Balance.hatamoto_resistance^2,
|
||||
radius = (1 - Balance.hatamoto_damage_taken_multiplier)^2,
|
||||
only_in_alt_mode = false,
|
||||
draw_on_ground = true,
|
||||
}
|
||||
@ -129,7 +127,7 @@ function Public.class_renderings(tickinterval)
|
||||
target = player.character,
|
||||
color = CoreData.colors.toughness_rendering,
|
||||
filled = false,
|
||||
radius = Balance.iron_leg_resistance^2,
|
||||
radius = (1 - Balance.iron_leg_damage_taken_multiplier)^2,
|
||||
only_in_alt_mode = false,
|
||||
draw_on_ground = true,
|
||||
}
|
||||
@ -169,14 +167,25 @@ function Public.update_character_properties(tickinterval)
|
||||
local player_index = player.index
|
||||
local character = player.character
|
||||
if memory.classes_table and memory.classes_table[player_index] then
|
||||
--local max_reach_bonus = 0
|
||||
-- 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
|
||||
|
||||
if memory.classes_table[player_index] == Classes.enum.FISHERMAN then
|
||||
character.character_reach_distance_bonus = 10
|
||||
elseif memory.classes_table[player_index] == Classes.enum.MASTER_ANGLER or memory.classes_table[player_index] == Classes.enum.DREDGER then
|
||||
character.character_reach_distance_bonus = 16
|
||||
character.character_reach_distance_bonus = Balance.fisherman_reach_bonus
|
||||
elseif memory.classes_table[player_index] == Classes.enum.MASTER_ANGLER then
|
||||
character.character_reach_distance_bonus = Balance.master_angler_reach_bonus
|
||||
elseif memory.classes_table[player_index] == Classes.enum.DREDGER then
|
||||
character.character_reach_distance_bonus = Balance.dredger_reach_bonus
|
||||
else
|
||||
character.character_reach_distance_bonus = 0
|
||||
end
|
||||
|
||||
--character.character_reach_distance_bonus = max_reach_bonus
|
||||
end
|
||||
|
||||
local health_boost = 0 -- base health is 250
|
||||
@ -198,13 +207,14 @@ function Public.update_character_properties(tickinterval)
|
||||
character.character_health_bonus = health_boost
|
||||
|
||||
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 + 0.85
|
||||
speed_boost = speed_boost * Balance.respawn_speed_boost
|
||||
else
|
||||
if memory.classes_table and memory.classes_table[player_index] then
|
||||
local class = memory.classes_table[player_index]
|
||||
if class == Classes.enum.SCOUT then
|
||||
speed_boost = speed_boost + 0.35
|
||||
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
|
||||
@ -213,27 +223,27 @@ function Public.update_character_properties(tickinterval)
|
||||
|
||||
if class == Classes.enum.DECKHAND then
|
||||
if on_ship_bool and (not hold_bool) then
|
||||
speed_boost = speed_boost + 0.25
|
||||
speed_boost = speed_boost * Balance.deckhand_extra_speed
|
||||
end
|
||||
elseif class == Classes.enum.BOATSWAIN then
|
||||
if hold_bool then
|
||||
speed_boost = speed_boost + 0.25
|
||||
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 + 0.07
|
||||
speed_boost = speed_boost * Balance.shoresman_extra_speed
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
character.character_running_speed_modifier = speed_boost
|
||||
character.character_running_speed_modifier = speed_boost - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.class_rewards_tick(tickinterval)
|
||||
--assuming tickinterval = 6 seconds for now
|
||||
--assuming tickinterval = 7 seconds for now
|
||||
local memory = Memory.get_crew_memory()
|
||||
|
||||
local crew = Common.crew_get_crew_members()
|
||||
@ -262,7 +272,7 @@ function Public.class_rewards_tick(tickinterval)
|
||||
end
|
||||
|
||||
|
||||
if game.tick % tickinterval == 0 and (not (memory.boat and memory.boat.state and (memory.boat.state == Structures.Boats.enum_state.ATSEA_LOADING_MAP or memory.boat.state == Structures.Boats.enum_state.ATSEA_WAITING_TO_SAIL))) then --it is possible to spend extra time here, so don't give out freebies
|
||||
if game.tick % tickinterval == 0 and (not (memory.boat and memory.boat.state and memory.boat.state == Structures.Boats.enum_state.ATSEA_LOADING_MAP)) then --it is possible to spend extra time here, so don't give out freebies
|
||||
|
||||
if memory.classes_table and memory.classes_table[player_index] then
|
||||
local class = memory.classes_table[player_index]
|
||||
@ -273,16 +283,16 @@ function Public.class_rewards_tick(tickinterval)
|
||||
local hold_bool = surfacedata.type == Surfaces.enum.HOLD
|
||||
|
||||
if class == Classes.enum.DECKHAND and on_ship_bool and (not hold_bool) then
|
||||
Classes.class_ore_grant(player, 2)
|
||||
Classes.class_ore_grant(player, Balance.deckhand_ore_grant_multiplier, Balance.deckhand_ore_scaling_enabled)
|
||||
elseif class == Classes.enum.BOATSWAIN and hold_bool then
|
||||
Classes.class_ore_grant(player, 4)
|
||||
Classes.class_ore_grant(player, Balance.boatswain_ore_grant_multiplier, Balance.boatswain_ore_scaling_enabled)
|
||||
elseif class == Classes.enum.SHORESMAN and (not on_ship_bool) then
|
||||
Classes.class_ore_grant(player, 2)
|
||||
Classes.class_ore_grant(player, Balance.shoresman_ore_grant_multiplier, Balance.shoresman_ore_scaling_enabled)
|
||||
elseif class == Classes.enum.QUARTERMASTER then
|
||||
local nearby_players = #player.surface.find_entities_filtered{position = player.position, radius = Common.quartermaster_range, name = 'character'}
|
||||
local nearby_players = #player.surface.find_entities_filtered{position = player.position, radius = Balance.quartermaster_range, name = 'character'}
|
||||
|
||||
if nearby_players > 1 then
|
||||
Classes.class_ore_grant(player, nearby_players - 1, true)
|
||||
Classes.class_ore_grant(player, nearby_players - 1, Balance.quartermaster_ore_scaling_enabled)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user