1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-11 13:39:14 +02:00

Merge branch 'develop' into develop

This commit is contained in:
Gerkiz 2022-06-07 17:43:37 +02:00 committed by GitHub
commit fa5e856b11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
108 changed files with 4818 additions and 1899 deletions

View File

@ -6,28 +6,370 @@ softmod_info_body_1=News and chat: getcomfy.eu/discord
softmod_info_game_description_1=Game Description
softmod_info_game_description_2=Set sail in this multiplayer scenario. Collect resources and fuel the ship in order to survive as many leagues as possible. The ship moves with code magic. Each crew has a captain, who performs actions such as deciding when the boat leaves. Doubloons can be spent at various markets throughout the game.\n\nGame progression is significantly slowed the smaller the crew.\n\n[font=default-bold]Win condition:[/font] Travel 1000 leagues.\n[font=default-bold]Lose condition:[/font] The ship runs out of fuel, or a cannon is destroyed.
softmod_info_bugs_1=Known issues
softmod_info_bugs_2=
# softmod_info_bugs_1=Known issues
# softmod_info_bugs_2=
softmod_info_new_players_1=For New Players
softmod_info_new_players_2=Mine coal and other resources and bring them to the ship to keep things going, or try asking the captain for more specific tasks.
softmod_info_tips_1=Features of the game that are hard to work out alone
softmod_info_tips_2=You can steer the boat from the crow's nest by placing 100 rail signals in one of the blue boxes.\n• Resources granted to the ship appear in the captain's cabin.\n• Charging a silo launches a rocket. This causes pollution and evo, but gives a reward of fuel and doubloons.\n• Charging a silo drains power from everything else on its network.\n• The quantity of ore available on an island is independent of the order in which you break rocks.\n• Passive pollution ramps up over time on each island.\n• The strength of attacks is proportional to the number of remaining nests. (The time-based rate of evolution is proportional to nests too, but destroying a nest will immediately jump evolution by most of the amount it 'would have' made had it survived.)\n• Covered markets give back any plates spent to unlock them.\n• Lab productivity increases with each league.\n• The player who spent the longest as captain between leagues 0 and 1000 (exclusive) is written into the highscores table.\n• Logged-out players keep their items with them for a while — except 'important' items that are returned to the crew immediately.\n• Commands: /ccolor gives you a fun color. /classinfo {classname} gives the description of the named class. To manage your class, use /take {classname} or /giveup. Captains also have /undock, /req, /officer, /plank.
softmod_info_tips_2=The captain can steer the boat from the crow's nest by placing 100 rail signals in one of the blue boxes.\n• Resources granted to the ship appear in the captain's cabin.\n• Charging a silo drains power from everything else on its network.\n• The quantity of ore available on an island is independent of the order in which you break rocks.\n• Passive pollution ramps up over time on each island.\n• The strength of attacks is proportional to the number of remaining nests. (The time-based rate of evolution is proportional to nests too, but destroying a nest will immediately jump evolution by most of the amount it 'would have' made had it survived.)\n• Lab productivity increases with each league.\n• item-on-ground entities on the deck are moved to the cabin when the boat moves, for performance reasons.\n• Commands: /ccolor gives you a fun color. /classinfo {classname} gives the description of the named class. To manage your class, use /take {classname} or /giveup.
softmod_info_updates_1=Recent changes
softmod_info_updates_2=v1.1.2.2.2\n- Some rebalancing of Nightmare difficulty\n\nv1.1.2.2.1\n- Downsides from some classes removed.\n- Small bugfixes\n\nv1.1.2.2.0\n- Coin requisitioning replaced by a 'tax' that takes only 10% of each player's coins.\n- Scaled up coin economy; rocket coin rewards now default to the second reward chest.\n- Deckhand nerfed.
softmod_info_updates_1=Significant recent changes
softmod_info_updates_2=v1.2.13\n• Added /classinfofull command.\n• Starting player items buffed.\n\nv1.2.11\n• Class costs reduced at quest structures.\n• Unlimited time can now be spent at sea between each destination.\n\nv1.2.8\n• Poison damage against players buffed\n• Maze treasure buffed\n\nv1.2.3\n• Rework of 'quest buildings' that appear on islands.\n• Fixed stutter when loading certain maps, such as swamp.\n\nv1.2\n• Mod portal release.
softmod_info_credits_1=Credits
softmod_info_credits_2=Pirate Ship designed and coded by thesixthroc. Comfy codebase and help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Some island structure blueprints contributed by Mattisso.\n\nthesixthroc is looking for coders to help implement planned features for this mod. Come chat with us: https://getcomfy.eu/discord\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
softmod_info_credits_2=Pirate Ship designed and coded by thesixthroc. Comfy codebase and help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Some island structure blueprints contributed by Mattisso.\n\nCome chat with us: https://getcomfy.eu/discord\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
softmod_info_credits_2_old=Softmod designed and written by thesixthroc. Comfy codebase help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Some island structure blueprints were contributed by Mattisso. Gold sprite by Clint Bellanger. Parrot sprites by @pixelthen.\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
thesixthroc_support_toast=Support Pirate Ship scenario design at ko-fi.com/thesixthroc
softmod_info_body_promote=by thesixthroc
softmod_info_body_promote_old2=patreon.com/thesixthroc
softmod_info_body_clicky=Click to dismiss.
softmod_info_body_some_old_stuff="Those white gloves. I'll never forget them 'till the day I die." - Dr. John
separator_1=,
separator_2= and
notify_whisper=[Whisper]
notify_parrot=Parrot:
location_displayname_first_1=Fledgling Vale
location_displayname_horseshoe_1=Shark Keys
location_displayname_horseshoe_2=Little Keys
location_displayname_horseshoe_3=Little Keys
location_displayname_maze_1=Bewildering Maze
location_displayname_radioactive_1=Abandoned Labs
location_displayname_red_desert_1=Sandworm Caldera
location_displayname_standard_1=Isle of Buried Treasure
location_displayname_standard_variant_1=Secluded Dells
location_displayname_swamp_1=Poisonous Fen
location_displayname_walkways_1=Frozen Pools
location_displayname_sea_1=
location_displayname_dock_1=Dock
location_displayname_lobby_1=Starting Dock
parrot_set_sail_advice=Ready to sail to the next island? Click up top!
parrot_hard_praise=Steel chests for steel players! Squawk!
parrot_normal_praise=Iron chests for iron players! Squawk!
parrot_fuel_warning=Fuel is low!
parrot_silo_warning=The silo is attracting biters...
parrot_0=We can wait here for as long as we like.
parrot_night_warning=Did you know that biters deal more damage at night?
parrot_boats_warning=200 leagues? I think we're being chased...
parrot_kraken_warning=400 leagues coming up? What are those pink things I spy...
parrot_radioactive_tip_1=We'll need uranium-235 to push away from this island...
parrot_radioactive_tip_2=The biters don't care if we pollute here, but they evolve fast.
parrot_maze_tip_1=Something seems wrong with our minimap.
parrot_captain_first_time_in_cabin_hint=The captain can buy items in the cabin, such as rail signals to steer the ship.
difficulty_easy=Easy
difficulty_normal=Normal
difficutly_hard=Hard
difficulty_nightmare=Nightmare
notify_difficulty_vote=__1__ voted [color=__2__,__3__,__4__]for difficulty __5__[/color]
notify_difficulty_change=Difficulty [color=__1__,__2__,__3__]changed to __4__[/color]
daynightcycle_static=Static
daynightcycle_slowcyclic=Slow Cyclic
daynightcycle_cyclic=Cyclic
daynightcycle_fastcyclic=Fast Cyclic
daynightcycle_rapidcyclic=Rapid Cyclic
ship_undocked_1=[font=heading-1]Ship undocked[/font] by captain.
ship_undocked_2=[font=heading-1]Ship auto-undocked[/font]. Return to ship.
ship_undocked_3=[font=heading-1]Ship auto-undocked[/font].
ship_set_off_to_next_island=[font=heading-1]Ship set sail[/font] for the next destination.
plank=__1__ planked __2__!
plank_error_invalid_player=Command error: Player is not a crewmember.
plank_error_self=Command error: Can't plank yourself.
tax=The captain taxed __1__.
tax_error_nothing=Tax error: No coins or game-critical items found in crewmates' inventories or cursor stacks.
respawn_speed_bonus_removed=Respawn speed bonus removed.
respawn_speed_bonus_applied=Respawn speed bonus applied.
find_map=__1__ found a map. Treasure location revealed.
find_ghost=__1__ found a ghost.
silo_destroyed=The silo was destroyed.
research_notification=__1__ researched.
destroyed_all_nests=All biter bases destroyed — escape cost removed.
recover_offline_player_items=Offline player's items recovered to cabin.
death_froze=__1__ froze to death.
death_pushed_into_water_by_cannon=__1__ was pushed into water by a cannon.
granted_rocket_launch=Rocket launched.
granted_kraken_kill=Kraken killed.
granted_periodic_barrel=
granted_quest_complete=Quest completed.
granted_1=__1__ __2__.
granted_2=__1__ __2__, __3__.
granted_3=__1__ __2__, __3__, __4__.
approaching_destination=Approaching destination __1__, __2__.
loading_destination=Loading destination __1__, __2__.
steer_left=Steering portside...
steer_right=Steering starboard...
error_undock_too_early=Undock error: Can't undock in the first 10 seconds.
error_undock_insufficient_resources=Undock error: Not enough resources stored in the captain's cabin.
error_cabin_full=Sadly, there wasn't space in the cabin for all of your reward.
error_build_undergrounds_on_boat=Build error: Undergrounds can't be built on the boat, due to conflicts with the boat movement code.
error_cant_carry_barrels=Recipe error: Barrels are too heavy to carry back to the ship. Try another way.
error_disembark=Now is no time to disembark.
quest_structure_market_1=Requires __1__x
quest_structure_market_2=(item components will be
quest_structure_market_3=refunded upon completion)
quest_structure_furnace_1=Requires
quest_structure_furnace_2=(the furnace breaks
quest_structure_furnace_3=delivered items down
quest_structure_furnace_4=into components)
market_description_upgrade_power=Upgrade the ship's passive power generators.
market_description_upgrade_hold=Purchase an extra hold.
market_description_upgrade_merchants=Unlock merchant ships on future islands.
market_description_upgrade_rockets=Unlock the sale of rockets at island markets.
market_description_purchase_class=Purchase the class __1__.
market_description_extra_time_at_sea=Relax at sea: Increase the next destination's loading time by 60 seconds.
market_event_sell=__1__ sold __2__ for __3__.
market_event_trade=__1__ traded away __2__ for __3__.
market_event_buy=__1__ bought __2__ for __3__.
extra_time_at_sea=extra time at sea
market_error_not_captain=Purchase error: You need to be a captain or officer to buy this.
market_error_not_captain_or_officer=Purchase error: You need to be a captain or officer to buy this.
market_error_maximum_loading_time=Purchase error: Reached the maximum allowed loading time.
repaired_cannons=[font=heading-1]__1__ repaired the ship's cannons.[/font]
upgrade_hold=[font=heading-1]__1__ upgraded the ship's hold.[/font]
upgrade_power=[font=heading-1]__1__ upgraded the ship's power.[/font]
upgrade_merchants=[font=heading-1]__1__ unlocked merchant ships at future islands.[/font]
upgrade_rockets=[font=heading-1]__1__ unlocked the sale of rockets at future quest markets.[/font]
upgrade_hold_crowsnest_form=Extra Hold
upgrade_power_crowsnest_form=Power
upgrade_merchants_crowsnest_form=Unlock Merchants
upgrade_rockets_crowsnest_form=Unlock Rockets
hold_connections_label_inactive=inactive
hold_connections_label_to=to -__1__
hold_connections_label_from=from -__1__
surface_label_cabin=Captain's Cabin
surface_label_crowsnest=Crow's Nest
surface_label_hold_nth=Ship's Hold: -__1__
surface_label_hold=Ship's Hold
role_officer=Officer
role_officer_description=Assigned by the captain, officers can use the Captain's shop and access privileged chests.
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__
class_explanation_upgraded_class=__1__: An upgrade of __2__. __3__
class_purchase=__1__ bought the class __2__. ([font=scenario-message-dialog]__3__[/font])
class_upgrade=__1__ upgraded their class from __2__ to __3__ ([font=scenario-message-dialog]__4__[/font]).
class_take_spare=__1__ took the spare class __2__. ([font=scenario-message-dialog]__3__[/font])
class_give_spare=A spare __1__ class with given to __2__. ([font=scenario-message-dialog]__3__[/font])
class_give_up=__1__ gave up __2__.
class_becomes_spare=A __1__ class is now spare.
class_give_up_error_no_class=Class error: You don't have any class to give up.
class_revoke=__1__ revoked __2__ from __3__.
class_purchase_error_prerequisite_class=Class purchase error: You need to be a __1__ to buy this.
roles_confirm_captain=__1__ accepted the role of captain.
roles_confirm_captain_error_1=Command error: You're not the captain.
roles_confirm_captain_error_2=Command error: You're not temporary, so you don't need to accept.
roles_renounce_captain=__1__ renounces their title of captain.
roles_renounce_captain_error_1=Command error: But you're the only crew member...
roles_pass_captainhood=__1__ has passed their title of captain to __2__.
roles_lose_captainhood_by_afk=__1__ was afk.
roles_ask_player_about_captainhood_variant_1=__1__, would you like to be captain? If yes say /ok
roles_ask_player_about_captainhood_variant_2=__1__, captain? If yes say /ok
roles_ask_player_about_captainhood_variant_3=__1__, is it your turn to be captain? If yes say /ok
roles_make_officer=__1__ made __2__ an officer.
roles_make_officer_error_1=Command error: Player is invalid.
roles_make_officer_error_2=Command error: Can't promote yourself to officer.
roles_make_officer_error_3=Command error: Player is not a crewmember.
roles_unmake_officer=__1__ removed __2__ from officer status.
roles_unmake_officer_error_1=Command error: Player isn't an officer.
roles_unmake_officer_error_2=Command error: Player isn't a crewmember.
roles_resign_officer=__1__ resigned from officer status.
roles_notify_looking_for_captain=Looking for a suitable captain...
warn_nearly_afk_captain=Note: If you go idle as captain for too long, the role passes to another crewmember.
error_class_assign_redundant=Class error: You're already a __1__.
error_class_assign_unavailable_class=Class error: No spare class of that type is available.
personal_join_string_1=You have joined the crew '__1__' [Capacity __2__].
personal_join_string_2=You have joined the crew '__1__' [Capacity __2__, Difficulty [color=__3__,__4__,__5__] __6__[/color]].
goto_oldest_crew_with_large_capacity=There are multiple crews on this server. You have been placed in the oldest crew with large capacity.
goto_oldest_crew=There are multiple crews on this server. You have been placed in the oldest.
choose_chat_color=__1__ chose the color __2__
randomize_chat_color=__1__'s color randomized to __2__
crew_to_spectator=__1__ left the crew to become a spectator.
lobby_to_spectator=__1__ joined as a spectator.
lobby_to_spectator_2=__1__ left the lobby to spectate __2__.
spectator_to_lobby=__1__ stopped spectating and returned to the lobby.
lobby_to_crew=__1__ joined the crew.
lobby_to_crew_2=__1__ left the lobby to join __2__.
crew_leave=__1__ left the crew.
crew_launch=[__1__] Launched.
crew_disband=[__1__] Disbanded after __2__.
proposal_propose=__1__ proposed the run __2__ [Capacity __3__].
proposal_retracted=Proposal __1__ retracted.
proposal_abandoned=Proposal __1__ abandoned.
loading_new_game=Loading new game...
crew_summon=Crew summoned.
crew_continue_on_freeplay=The run now continues on 'Freeplay'.
crew_disbanded=__1__ disbanded __2__ after __3__.
victory=Victory, on v__1__, __2__, capacity __3__. Playtime: [font=default-large-semibold]__4__[/font] since 1st island. Crewmembers: __5__.
loss_cannon_destroyed=Game over — cannon destroyed.
loss_out_of_fuel=Game over — out of fuel.
loss_silo_destroyed=Game over — silo destroyed.
loss_silo_destroyed_before_necessary_launch=Game over — silo destroyed before a necessary launch.
loss_rest_of_message_long=Playtime: __1__ since 1st island. Crewmembers: __2__
loss_rest_of_message_short=Playtime: __1__ since 1st island.
highscore_heading_crew=Crew
highscore_heading_captain=Captain
highscore_heading_captain_tooltip=The player who spent the longest as captain between leagues 0 and 1000 (exclusive).
highscore_heading_completion=Completion
highscore_heading_leagues=Leagues
highscore_heading_version=Version
highscore_heading_difficulty=Difficulty
highscore_heading_peak_players=PeakPlayers
proposal_displayform=__1__ — __2__
run_displayform= __2__
@ -36,9 +378,10 @@ capacity_tooltip=Capacity. Sets the maximum number of crewmembers allowed.
difficulty_tooltip=Difficulty.\n\nHigher difficulties have higher pollution and evo, higher biter damage, lower gold loot, but higher chest loot, along with small effects on the time per island, quest requirements, and silo position.\n\nDifficulty also determines the material the ship is made out of.
mode_tooltip=Mode.
auto_undock_tooltip=The maximum time to stay at this location.\n\nOnce this time is reached, the boat undocks automatically. The captain can choose to leave earlier by pressing this button.
auto_undock_tooltip=The maximum time to stay at this location.\n\nOnce this time is reached, the boat undocks automatically. The captain can choose to leave earlier by pressing this button (or typing /undock).
atsea_loading_tooltip=The next destination is loading.
leave_anytime_tooltip=The captain chooses when to undock the ship.\n\nThey can undock by pressing this button.
atsea_waiting_tooltip=The ship pauses after each destination. When the captain is ready, they can click this button to proceed.
resources_needed_tooltip_0=At the next destination, these resources will be needed in order to undock.
resources_needed_tooltip_1=At the next destination, these resources will be needed in order to undock early.\n\nFewer resources will be needed the longer you stay, eventually dropping to zero.
@ -49,4 +392,143 @@ resources_needed_tooltip_0_rocketvariant=At the next destination, these resource
resources_needed_tooltip_1_rocketvariant=At the next destination, these resources will be needed in order to undock early.\n\nFewer resources will be needed the longer you stay, eventually dropping to zero.\n\nThe silo represents a rocket launch rather than a resource.
resources_needed_tooltip_2_rocketvariant=The captain can undock early by clicking this button, but only if enough resources have been stored in the captain's cabin.\n\nThe silo represents a rocket launch rather than a resource.\n\nnCost on arrival: __1__\nLeaving now will spend: __2__
resources_needed_tooltip_3_rocketvariant=The captain can undock by clicking this button, but only if enough resources are stored in the captain's cabin.\n\nThe silo represents a rocket launch rather than a resource.
fuel_tooltip=Stored fuel: __1__.\n\nTo store more, send it to the captain's cabin. If the ship runs out of fuel, the crew loses.
fuel_tooltip=Stored fuel: __1__.\n\nTo store more, send it to the captain's cabin. If the ship runs out of fuel, the crew loses.
gui_crew_window_buttons_quit_crew=Quit Crew
gui_crew_window_buttons_quit_crew_tooltip=Return to the lobby.
gui_crew_window_buttons_quit_spectators=Return to Lobby
gui_crew_window_buttons_join_crew=Join Crew
gui_crew_window_buttons_join_spectators=Spectate
gui_crew_window_buttons_join_spectators_tooltip=You won't be able to rejoin the crew for a short while after you do this.
gui_crew_window_crewmembers=Crew Members
gui_crew_window_crewmembers_give_up_class=Give Up Class
gui_crew_window_crewmembers_give_up_class_tooltip=Give Up Class
gui_crew_window_crewmembers_resign_as_officer=Resign as Officer
gui_crew_window_crewmembers_resign_as_officer_tooltip=Give up the officer role.
gui_crew_window_spectators=Spectators
gui_crew_window_vote_for_difficulty=Vote for Difficulty
gui_crew_window_spare_classes=Spare Classes
gui_crew_window_assign_class_button=Give class: __1__
gui_crew_window_assign_class_button_tooltip=Give the selected player the class __1__.\n\n Class description: __2__
gui_crew_window_selfassign_class_button=Take class: __1__
gui_crew_window_selfassign_class_button_tooltip=Give yourself the spare class __1__.\n\n Class description: __2__
gui_crew_window_captains_actions=Captain's Actions
gui_crew_window_captains_actions_disband_crew=Disband Crew
gui_crew_window_captains_actions_disband_crew_tooltip=End the run. You will be prompted again after clicking.
gui_crew_window_captains_actions_disband_crew_check=ARE YOU SURE?
gui_crew_window_captains_actions_disband_crew_check_tooltip=Click again to disband the crew.
gui_crew_window_captains_actions_renounce_title=Renounce Captainhood
gui_crew_window_captains_actions_renounce_title_tooltip=You will no longer be captain, and the role will be passed around until a crewmember takes it.
gui_crew_window_captains_actions_pass_title=Pass Captain To
gui_crew_window_captains_actions_pass_title_tooltip=Make the selected crewmember into the Captain.
gui_crew_window_captains_actions_plank=Plank (Make Spectator)
gui_crew_window_captains_actions_plank_tooltip=The player will be returned to the lobby and can't join your crew for a while. (or use /plank {player})
gui_crew_window_captains_actions_make_officer=Make Officer
gui_crew_window_captains_actions_make_officer_tooltip=Make this player an Officer. (or use /officer {player})
gui_crew_window_captains_actions_unmake_officer=Unmake Officer
gui_crew_window_captains_actions_unmake_officer_tooltip=Remove this player as an Officer. (or use /officer {player})
gui_crew_window_captains_actions_revoke_class=Revoke Class
gui_crew_window_captains_actions_revoke_class_tooltip=Put this player's class back in the Spare Classes pool.
gui_crew_window_captains_actions_summon_crew=Summon Crew to Ship
gui_crew_window_captains_actions_summon_crew_tooltip=Teleport crewmembers to the ship.
gui_crew_window_captains_actions_tax=Tax Crew
gui_crew_window_captains_actions_tax_tooltip=For each non-officer in your crew, take __1__% of their doubloons (and their other game-critical items). (or use /tax)
gui_crew_window_captains_actions_undock_tip=To undock, use the top toolbar.
gui_crew_window_crew_age=Age: __1__
gui_crew_window_crew_capacity_and_difficulty=__1__, Capacity __2__.
gui_crew_window_crew_count=Crew Members (__1__)
gui_evo_tooltip_1=Local Biter Evolution: __1__
gui_evo_tooltip_2=Leagues: __1__
gui_evo_tooltip_3=Kraken: __1__
gui_evo_tooltip_4=Time: __1__
gui_evo_tooltip_5=Silo: __1__
gui_evo_tooltip_6=Nests: __1__
gui_evo_tooltip_7=Sandwurms: __1__
gui_info_info=Info
gui_info_updates=Updates
gui_info_tips=Tips
gui_info_credits=Credits
gui_fuel_1=Fuel:
gui_minimap_tooltip=LMB: Zoom in.\nRMB: Zoom out.\nMMB: Scale window.
gui_minimap_outside_view=Outside View
gui_minimap_switch_left=Auto Show Map — On
gui_minimap_switch_right=Off
gui_progress=Progress
gui_progress_distance_travelled=Distance travelled:
gui_progress_leagues=__1__ leagues
gui_progress_current_location=Current location: __1__
gui_progress_time_of_day=Time of day: __1__
gui_runs_play=Play
gui_runs_ongoing_runs=Ongoing Runs
gui_runs_ongoing_runs_helpful_tip=To join a run, first select it in the table below.
gui_runs_ongoing_runs_spectate=Spectate
gui_runs_ongoing_runs_join_crew=Join Crew
gui_runs_ongoing_runs_return_to_lobby=Return to Lobby
gui_runs_ongoing_runs_hop_on_board=Hop on board.
gui_runs_proposals=Proposals
gui_runs_proposals_endorse_proposal=Endorse Proposal
gui_runs_proposals_retract_endorsement=Retract Endorsement
gui_runs_proposals_abandon_proposal=Abandon Proposal
gui_runs_proposal_maker_run_name=Run name
gui_runs_proposal_maker_run_name_2=Name
gui_runs_proposal_maker_capacity=Capacity
gui_runs_proposal_maker_capacity_disabled=This capacity setting isn't available at the moment.
gui_runs_proposal_maker_propose=Propose
gui_runs_proposal_maker_no_limit=No limit
gui_runs_launch=Launch run
gui_runs_launch_error_1=Gather endorsements from more pirates.
gui_runs_launch_error_2=The number of concurrent runs on the server has reached the cap set by the admins.
gui_runs_launch_error_3=Can't launch; at least one run needs high player capacity.
gui_runs_launch_error_4=No sloops available. Join an existing run instead.
gui_runs_wait_to_join=Wait to join... __1__
gui_info_main_tooltip=Notes and updates on Pirate Ship.
gui_crews=Crews
gui_crews_main_tooltip=View the ongoing runs, and make proposals for new ones.
gui_minimap_main_tooltip=View the outside world.
gui_etaframe_board_warning=RETURN TO SHIP
gui_etaframe_board_warning_tooltip=Probably time to board...
gui_etaframe_autoundock=Auto-undock:
gui_etaframe_arriving_in=Arriving in
gui_etaframe_atsea_waiting=Captain — Click here to Sail
gui_etaframe_undock=Undock:
gui_etaframe_anytime=Anytime
gui_etaframe_nest_escape_cost=Next escape cost:
gui_etaframe_to_escape_store=To escape, store
gui_etaframe_or_store=Or store
gui_etaframe_rocket_requirement_tooltip=Launch a rocket
gui_etaframe_undock_are_you_sure=Undock — Are you sure?
gui_etaframe_launched=Launched:
gui_etaframe_launched_tooltip=This island's rocket has launched, and this is the reward.
gui_etaframe_launching=The rocket is launching...
gui_etaframe_charge=Charge:
gui_etaframe_charge_tooltip=Rocket silo charge: __1__/__2__ GJ\n\nFully charge the silo to launch a rocket, gaining both doubloons and fuel.
gui_questframe=Island Quest:
gui_questframe_fail=Fail
gui_questframe_ok=OK
gui_questframe_complete_tooltip=This island's quest is complete, and this is the reward.
gui_questframe_time=Island Quest: Time\n\nLaunch a rocket before the countdown completes for a bonus.
gui_questframe_worms=Island Quest: Worms\n\nKill enough worms for a bonus.
gui_questframe_find=Island Quest: Ghosts\n\nFind the ghosts for a bonus.
gui_questframe_resourceflow=Island Quest: Resource Flow\n\nAchieve a production rate of a particular item for a bonus.
gui_questframe_resourcecount=Island Quest: Item Production\n\nSimply complete production of these items for a bonus, anywhere on the map.
gui_questframe_nodamage=Island Quest: No Damage\n\nLaunch a rocket without the silo taking damage.
gui_crew_tooltip_1=Your Crew\n\nPerform crew actions, such as selecting a class if any are available.
gui_crew_tooltip_2=Your Crew\n\nYou're a free agent, so there's nothing to do here.
gui_progress_tooltip=Progress: __1__ leagues.\n\nTravel __2__ leagues to win the game.

515
locale/zh-CN/pirates.cfg Normal file
View File

@ -0,0 +1,515 @@
[pirates]
softmod_info_header_before_version_number==== 海盗船 v
softmod_info_header_after_version_number= ===
softmod_info_body_1=最新消息和聊天: getcomfy.eu/discord
softmod_info_game_description_1=游戏介绍
softmod_info_game_description_2=在这个多人游戏场景中启航。收集资源并为船添加燃料,以便尽可能航行更多的里格(距离单位)。 船使用代码魔法移动。每个团队都有一名船长,他决定船何时出坞等行动。达布隆(金币)可以在整个游戏中不同的市场上花费。\n\n团队人数越少,游戏进程越慢。\n\n[font=default-bold]获胜条件:[/font] 航行1000里格。\n[font=default-bold]失败条件:[/font] 船耗尽燃料或重炮被摧毁。
# softmod_info_bugs_1=已知问题
# softmod_info_bugs_2=•
softmod_info_new_players_1=对于新手的建议
softmod_info_new_players_2=开采煤炭和其他资源并将它们带到船上,或者向船长询问更具体的任务。
softmod_info_tips_1=这个模式单人难以完成
softmod_info_tips_2=• 船长可以通过在瞭望台的蓝色箱子中放置100个铁路信号来驾驶船舶向左或向右转。在船头的蓝箱放置信号灯可以微调登陆点\n• 赠予船的资源会出现在船长舱中,请及时取出避免爆仓。\n• 为发射井充电会消耗所在电网中的所有电力。发射井被摧毁不再导致游戏失败,除非该关卡有要求。\n• 岛上可用的矿石数量与你打碎岩石的顺序无关。\n• 每个岛上的被动污染随着时间的推移而增加。\n• 攻击的强度与剩余虫巢数成正比。 (基于时间的进化速度也与虫巢成正比,但破坏虫巢会立即使进化值跳跃,比让虫巢活着“本应”产生的还要多。)\n• 实验室产能随着航行里格数增加而提高。\n• 离线的玩家可以将他们的物品随身携带一段时间——除了那些需要立即归还给团队的“重要”物品。\n• 当船移动时,甲板上的落地物品会被移至船舱,为了更好的性能表现。\n• 命令: /ccolor 随机一个有趣的颜色。 /classinfo {classname} 给出指定职业的描述(注意职业名称必须使用英文,例如/classinfo deckhand)。想要管理你的职业,请使用 /take {classname} 成为指定职业或 /giveup放弃当前职业。虫子尸体太多,请使用/clear-corpses 50 ,参数可以自己修改,最好不要超过500。船长还有以下命令:/tax(向非军官船员征税), /undock(提前出坞), /officer(任命军官), /plank(让某人跳甲板)。
softmod_info_updates_1=近期重要更新
softmod_info_updates_2=v1.2.11\n• 职业花费降低\n• 在海上不再限制时间,尽情享受闲暇时光。\n\nv1.2.8\n• 提高对玩家的中毒伤害。\n• 增强迷宫宝藏。\n• 虫子更倾向于成群进攻。\n\nv1.2.3\n• 重做岛屿上出现的“任务建筑”。\n• 修复了加载某些地图时出现的卡顿问题,例如沼泽。\n• 各种新的适合玩家的视觉渲染。\n• 翻译成其他语言的Mod准备。\n• 扩展了美食家的味觉。
softmod_info_credits_1=工作人员
softmod_info_credits_2=海盗船由 thesixthroc 设计和编码。 Comfy 代码基础和帮助来自 Gerkiz, Hanakocz 和 Mew @ Comfy Industries (https://getcomfy.eu)。一些由 Mattisso 提供的岛屿结构蓝图。\n\n汉化:dwightkung\n\n 欢迎来和我们聊天: https://getcomfy.eu/discord\n\n"那些白手套。我永远不会忘记它们,直到我死去的那一天。" - Dr. John
softmod_info_credits_2_old=Softmod designed and written by thesixthroc. Comfy codebase help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Some island structure blueprints were contributed by Mattisso. Gold sprite by Clint Bellanger. Parrot sprites by @pixelthen.\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
thesixthroc_support_toast=如果你喜欢这个场景,欢迎给我买一杯咖啡:ko-fi.com/thesixthroc
softmod_info_body_promote=由 thesixthroc 制作
softmod_info_body_promote_old2=欢迎到patreon.com/thesixthroc支持我
softmod_info_body_clicky=我知道了
separator_1=,
separator_2=
notify_whisper=[私信]
notify_parrot=鹦鹉:
location_displayname_first_1=羽翼未丰的山谷
location_displayname_horseshoe_1=鲨鱼钥匙
location_displayname_horseshoe_2=小钥匙
location_displayname_horseshoe_3=小钥匙
location_displayname_maze_1=迷惑迷宫
location_displayname_radioactive_1=废弃实验室
location_displayname_red_desert_1=沙丘 D U N E
location_displayname_standard_1=埋藏宝藏岛
location_displayname_standard_variant_1=僻静的山谷
location_displayname_swamp_1=剧毒沼泽
location_displayname_walkways_1=冰冻水池
location_displayname_sea_1=
location_displayname_dock_1=码头
location_displayname_lobby_1=初始码头
parrot_set_sail_advice=准备好前往下个小岛了吗? 点击顶部按钮!
parrot_hard_praise=钢铁的玩家才配得上钢箱子!嘎嘎!
parrot_normal_praise=铁打的玩家才配得上铁箱子!嘎嘎!
parrot_fuel_warning=燃料不足!
parrot_silo_warning=发射井正在吸引虫群...
parrot_0=我们可以在这里待到天荒地老,海枯石烂。
parrot_night_warning=你知道吗?虫子在晚上造成的伤害更大
parrot_boats_warning=唔!200 里格?我想我们正在被虫群追赶...
parrot_kraken_warning=400 里格即将到来?那些粉红色的东西是什么,我发现...
parrot_radioactive_tip_1=我们需要 铀-235 才能离开这个岛...
parrot_radioactive_tip_2=虫子不在乎我们是否污染这里,但污染使它们进化得很快。
parrot_maze_tip_1=我们的小地图似乎有问题。
parrot_captain_first_time_in_cabin_hint=船长可以在船长舱内购买物品,例如用于驾驶船只的铁路信号灯。
difficulty_easy=简单
difficulty_normal=正常
difficutly_hard=困难
difficulty_nightmare=噩梦
notify_difficulty_vote=__1__ 投了 [color=__2__,__3__,__4__] __5__难度[/color]
notify_difficulty_change=难度 [color=__1__,__2__,__3__]更改为 __4__[/color]
daynightcycle_static=静态
daynightcycle_slowcyclic=缓慢循环
daynightcycle_cyclic=正常循环
daynightcycle_fastcyclic=快速循环
daynightcycle_rapidcyclic=极速循环
ship_undocked_1=英明的船长决定[font=heading-1]船舶提前出坞[/font]
ship_undocked_2=[font=heading-1]船舶自动出坞[/font]。速回。
ship_undocked_3=[font=heading-1]船舶自动出坞[/font]。
ship_set_off_to_next_island=[font=heading-1]启航[/font] 前往下个目的地。
plank=__1__ 命令 __2__跳甲板!
plank_error_invalid_player=命令错误:玩家不是船员。
plank_error_self=命令错误:不能让自己跳甲板。
tax=船长征税__1__。
tax_error_nothing=在队友的物品栏或光标堆栈中找不到硬币或游戏关键物品。
respawn_speed_bonus_removed=重生速度加成失效。
respawn_speed_bonus_applied=重生速度加成生效。
find_map=__1__ 找到了一张地图。宝藏位置已揭晓!
find_ghost=__1__ 发现了一个幽灵!
silo_destroyed=发射井被摧毁。
research_notification=__1__ 研究完成。
destroyed_all_nests=所有的虫巢被摧毁——逃生费用已移除。
recover_offline_player_items=离线玩家的物品已被回收到船舱。
death_froze=__1__ 被冻死了。
death_pushed_into_water_by_cannon=__1__ 被重炮推入了水中。
granted_rocket_launch=火箭已发射。
granted_kraken_kill=海怪已击杀。
granted_periodic_barrel=
granted_quest_complete=任务完成。
granted_1=__1__ 奖励: __2__.
granted_2=__1__ 奖励:__2__, __3__.
granted_3=__1__ 奖励:__2__, __3__, __4__.
approaching_destination=接近目的地 __1__, __2__.
loading_destination=加载目的地 __1__, __2__.
steer_left=左舷转向...
steer_right=右舷转向...
error_undock_too_early=出坞错误:前 10 秒内无法出坞。
error_undock_insufficient_resources=出坞错误: 船长舱没有足够的资源存储。
error_cabin_full=很遗憾,船长舱内没有空间来盛放您所有的奖励。
error_build_undergrounds_on_boat=建造错误:由于与船移动代码冲突,无法在船上建造地下建筑。
error_cant_carry_barrels=配方错误:桶太重,无法运回船上。请尝试另一种方式。
error_disembark=现在不是下船的时候。
quest_structure_market_1=需要__1__x
quest_structure_market_2=(物品材料将在
quest_structure_market_3=任务完成后返还)
quest_structure_furnace_1=需要
quest_structure_furnace_2=(熔炉可以将
quest_structure_furnace_3=已交付的物品
quest_structure_furnace_4=立即拆分成原始材料)
market_description_upgrade_power=升级船舶的被动发电机。
market_description_upgrade_hold=购买额外的船舱。
market_description_upgrade_merchants=解锁未来岛屿上的商船。
market_description_upgrade_rockets=在岛屿市场解锁火箭弹销售。
market_description_purchase_class=购买职业 __1__。
market_description_extra_time_at_sea=在海上多放松一分钟:将下一个目的地的加载时间增加 60 秒。
market_event_sell=__1__ 以 __3__ 的价格售出 __2__.
market_event_trade=__1__ 用 __2__ 换取 __3__.
market_event_buy=__1__ 以 __3__ 的价格购买 __2__.
extra_time_at_sea=在海上多放松一分钟
market_error_not_captain=购买错误:您需要成为船长或军官才能购买。
market_error_not_captain_or_officer=购买错误:您需要成为船长或军官才能购买。
market_error_maximum_loading_time=购买错误:已达到最大允许加载时间。
repaired_cannons=[font=heading-1]__1__ 修复了船上的重炮。[/font]
upgrade_hold=购买了额外的船舱。
upgrade_power=升级了船舶的被动发电机。
upgrade_merchants=解锁未来岛屿上的商船。
upgrade_rockets=在岛屿市场解锁火箭弹的销售。
upgrade_hold_crowsnest_form=额外船舱
upgrade_power_crowsnest_form=发电机升级
upgrade_merchants_crowsnest_form=解锁商船
upgrade_rockets_crowsnest_form=解锁火箭弹
hold_connections_label_inactive=未激活
hold_connections_label_to=通向 -__1__
hold_connections_label_from=来自 -__1__
surface_label_cabin=船长舱
surface_label_crowsnest=瞭望台
surface_label_hold_nth=下层船舱: __1__
surface_label_hold=下层船舱
role_officer=军官
role_officer_description=由船长任命,军官可以使用船长的商店以及旁边的钢箱。
role_captain=船长
role_captain_description=拥有提前驶出船坞、购买物品和其他各种特殊行动的执行权。游戏在指定队长时,会优先考虑那些作为非队长出场时间最长的人。
class_deckhand=水手
class_deckhand_explanation=Deckhand,在甲板上的时候移动得较快并且为船舱生成矿石。
class_fisherman=渔夫
class_fisherman_explanation=Fisherman,捕鱼的距离较远。
class_scout=侦察兵
class_scout_explanation=Scout,速度较快,但身体脆弱且伤害低。
class_samurai=武士
class_samurai_explanation=Samurai,比较强壮,而且*没有装备武器*在近战中打得很好,但在其他方面表现不佳。
class_merchant=商人
class_merchant_explanation=Merchant,每个里格产生 50 达布隆。
class_shoresman=海岸人
class_shoresman_explanation=Shoresman,移动得稍微快一些,并且不在船上时为船舱生成矿石。
class_boatswain=水手长
class_boatswain_explanation=Boatswain,在甲板下面时移动较快并为船舱生成矿石。
class_prospector=勘探者
class_prospector_explanation=Prospector,在手工开采时会发现较多资源。
class_lumberjack=伐木工人
class_lumberjack_explanation=Lumberjack,在砍树时会找到较多的资源。
class_master_angler=钓鱼大师
class_master_angler_explanation=Master Angler,钓鱼的距离非常远,捕获的量也非常多。
class_wood_lord=森林之王
class_wood_lord_explanation=Lord of the Woods,在砍树时会发现非常多的资源。
class_chief_excavator=首席挖掘手
class_chief_excavator_explanation=Chief Excavator,在手工开采时发现了非常多的资源。
class_hatamoto=旗本武士
class_hatamoto_explanation=Hatamoto,非常强悍,而且*没有装备武器*近战打得很好,但其他方面就很差。
class_iron_leg=铁腿
class_iron_leg_explanation=Iron Leg,在携带 3000 铁矿石时非常强韧。
class_quartermaster=军需官
class_quartermaster_explanation=Quartermaster,为附近的船员提供+10%的物理攻击加成并为船舱生成矿石。
class_dredger=挖泥手
class_dredger_explanation=Dredger,在钓鱼时会发现令人惊奇的物品。
class_smoldering=闷烧师
class_smoldering_explanation=Smoldering,煤炭少于50时,会定期将木材转化为煤炭。
class_gourmet=美食家
class_gourmet_explanation=Gourmet,通过在奇特的地方吃鱼来为船长舱生成矿石。
class_explanation=__1__: __2__
class_explanation_upgraded_class=__1__: __2__的升级。 __3__
class_purchase=__1__ 购买了职业 __2__. ([font=scenario-message-dialog]__3__[/font])
class_upgrade=__1__ 将他们的职业从 __2__ 升级到了 __3__ ([font=scenario-message-dialog]__4__[/font]).
class_take_spare=__1__ 选择了空闲职业 __2__. ([font=scenario-message-dialog]__3__[/font])
class_give_spare=一个空闲的 __1__ 职业被授予 __2__。 ([font=scenario-message-dialog]__3__[/font])
class_give_up=__1__ 放弃了 __2__。
class_becomes_spare=一个 __1__ 职业 现在空闲。
class_give_up_error_no_class=职业错误:你没有任何职业可以放弃。
class_revoke=__1__ 从 __3__ 撤销了 __2__ 。
class_purchase_error_prerequisite_class=职业购买错误: 你需要成为 __1__ 才能购买。
roles_confirm_captain=__1__ 接受了船长的角色。
roles_confirm_captain_error_1=命令错误:你不是船长。
roles_confirm_captain_error_2=命令错误:你不是临时的,所以你不需要接受。
roles_renounce_captain=__1__ 放弃了船长头衔。
roles_renounce_captain_error_1=命令错误:但你是唯一的船员......
roles_pass_captainhood=__1__ 已将船长头衔授予 __2__.
roles_lose_captainhood_by_afk=__1__ 由于挂机被取消了船长身份。
roles_ask_player_about_captainhood_variant_1=__1__, 你想成为船长吗?如果接受请说/ok
roles_ask_player_about_captainhood_variant_2=__1__, 船长?船长便宜卖了 如果接受请说/ok
roles_ask_player_about_captainhood_variant_3=__1__,轮到你当船长了 如果接受请说/ok
roles_make_officer=__1__ 任命 __2__ 为军官
roles_make_officer_error_1=命令错误:玩家无效。
roles_make_officer_error_2=命令错误:不能将自己任命为军官。
roles_make_officer_error_3=命令错误:玩家不是船员。
roles_unmake_officer=__1__ 取消了 __2__ 的军官身份。
roles_unmake_officer_error_1=命令错误:玩家不是军官。
roles_unmake_officer_error_2=命令错误:玩家不是船员。
roles_resign_officer=__1__ 辞去了军官职务。
roles_notify_looking_for_captain=正在物色合适的船长...
warn_nearly_afk_captain=注意:如果您作为船长闲置的时间过长,该职业会传递给其他船员。
error_class_assign_redundant=职业错误: 你已经是 __1__了。
error_class_assign_unavailable_class=职业错误:没有空闲职业
personal_join_string_1=你已加入团队 '__1__' [容量 __2__].
personal_join_string_2=你已加入团队 '__1__' [容量 __2__, 难度 [color=__3__,__4__,__5__] __6__[/color]].
goto_oldest_crew_with_large_capacity=这台服务器上有多个团队。您已被安置在容量最大,创建最早的团队中。
goto_oldest_crew=这台服务器上有多个团队。您已被安置在创建最早的团队中。
choose_chat_color=__1__ 选择了颜色 __2__
randomize_chat_color=__1__的颜色随机成了 __2__
crew_to_spectator=__1__ 离开团队成为观众。
lobby_to_spectator=__1__ 作为观众加入。
lobby_to_spectator_2=__1__ 离开了大厅去观战 __2__.
spectator_to_lobby=__1__ 停止观战并返回大厅。
lobby_to_crew=__1__ 加入团队
lobby_to_crew_2=__1__ 离开大厅加入 __2__.
crew_leave=__1__离开了团队。
crew_launch=[__1__] 出发!
crew_disband=[__1__] 在 __2__后解散。
proposal_propose=__1__ 提议组建 __2__ [Capacity __3__]。
proposal_retracted=提案 __1__ 已撤回
proposal_abandoned=提案 __1__ 已废除
default_crew_name=未命名
loading_new_game=正在加载新游戏...
crew_summon=召唤船员。
crew_continue_on_freeplay=现在继续在“自由模式”上运行。
crew_disbanded=__1__ 在 __3__ 后解散 __2__ 。
victory=胜利! 在 v__1__, __2__, 容量 __3__. 游戏时间: [font=default-large-semibold]__4__[/font] 船员: __5__.
loss_cannon_destroyed=游戏结束 — 重炮被摧毁。
loss_out_of_fuel=游戏结束 — 燃料耗尽
loss_silo_destroyed=游戏结束 — 发射井被摧毁
loss_silo_destroyed_before_necessary_launch=游戏结束 — 发射井在必要的发射前被摧毁。
loss_rest_of_message_long=游戏时间: __1__ 自从第一个岛开始。船员: __2__
loss_rest_of_message_short=游戏时间: __1__ 自从第一个岛开始。
highscore_heading_crew=团队
highscore_heading_captain=船长
highscore_heading_captain_tooltip=在 0 到 1000 里格(不包括)之间担任船长时间最长的玩家。
highscore_heading_completion=完成
highscore_heading_leagues=里格数
highscore_heading_version=版本
highscore_heading_difficulty=难度
highscore_heading_peak_players=巅峰玩家
proposal_displayform=__1__ — __2__
run_displayform= __2__
crewmember_displayform=[color=__2__,__3__,__4__]__5__[/color] [color=1,1,1]__6__[/color]
capacity_tooltip=容量。设置允许的最大乘员人数。
difficulty_tooltip=难度。\n\n更高的难度有更高的污染和进化,更多的虫子,更少的金币战利品,但更高的宝箱战利品,并且对每个岛屿的时间、任务要求和发射井位置有些许影响。\n\n难度还决定了造船所用的材料。
mode_tooltip=模式.
auto_undock_tooltip=在这个位置停留的最长时间。\n\n一旦达到这个时间,船就会自动离岸。船长也可以通过按此按钮选择提前出坞(或使用/undock)。
atsea_loading_tooltip=下一个目的地正在加载。
leave_anytime_tooltip=船长选择何时启航。\n\n可以通过按此按钮离开船坞。
atsea_waiting_tooltip=船将在海上一直停留。如果船长准备继续冒险,请点击这个按钮。
resources_needed_tooltip_0=在下一个目的地,需要这些资源才能出坞。
resources_needed_tooltip_1=在下一个目的地,需要这些资源才能提前出坞。\n\n您停留的时间越长,所需的资源就越少,最终降至零。
resources_needed_tooltip_2=船长可以通过单击此按钮提前撤离,但前提是船长舱内储存了足够的资源。\n\n到达成本: __1__\n现在离开将花费: __2__
resources_needed_tooltip_3=船长可以通过单击此按钮来提前撤离,但前提是船长舱内储存了足够的资源。
resources_needed_tooltip_0_rocketvariant=下一个目的地,需要这些资源才能出坞。\n\n发射井代表火箭发射而不是资源。
resources_needed_tooltip_1_rocketvariant=在下一个目的地,将需要这些资源才能提前撤离。\n\n您停留的时间越长,所需的资源就越少,最终降至零。\n\n发射井代表火箭发射而不是资源。
resources_needed_tooltip_2_rocketvariant=船长可以通过单击此按钮提前撤离,但前提是船长舱内已储存了足够的资源。\n\n发射井代表火箭发射而不是资源。\n\nn到达成本: __1__\n现在离开将花费: __2__
resources_needed_tooltip_3_rocketvariant=船长可以通过单击此按钮提前撤离,但前提是船长舱内已储存了足够的资源。\n\n发射井代表火箭发射而不是资源。
fuel_tooltip=储存的燃料: __1__.\n\n要储存更多,请将其送到船长舱。如果船用完燃料,团队就会失败。
gui_crew_window_buttons_quit_crew=退出团队
gui_crew_window_buttons_quit_crew_tooltip=回到那个大厅
gui_crew_window_buttons_quit_spectators=回到大厅
gui_crew_window_buttons_join_crew=加入团队
gui_crew_window_buttons_join_spectators=观战
gui_crew_window_buttons_join_spectators_tooltip=您在执行此操作后的短时间内将无法重新加入船员。
gui_crew_window_crewmembers=船员们
gui_crew_window_crewmembers_give_up_class=放弃职业
gui_crew_window_crewmembers_give_up_class_tooltip=放弃职业
gui_crew_window_crewmembers_resign_as_officer=辞去军官职务
gui_crew_window_crewmembers_resign_as_officer_tooltip=放弃军官职务
gui_crew_window_spectators=观众
gui_crew_window_vote_for_difficulty=难度投票
gui_crew_window_spare_classes=空闲职业
gui_crew_window_assign_class_button=授予职业: __1__
gui_crew_window_assign_class_button_tooltip=任命此玩家为 __1__。\n\n 职业描述: __2__
gui_crew_window_selfassign_class_button=选择职业: __1__
gui_crew_window_selfassign_class_button_tooltip=授予自己空闲的职业 __1__.\n\n 职业描述: __2__
gui_crew_window_captains_actions=船长的行动
gui_crew_window_captains_actions_disband_crew=解散团队
gui_crew_window_captains_actions_disband_crew_tooltip=结束本次航行。点击后会再次提示。
gui_crew_window_captains_actions_disband_crew_check=你确定?
gui_crew_window_captains_actions_disband_crew_check_tooltip=再次点击解散团队
gui_crew_window_captains_actions_renounce_title=放弃船长头衔
gui_crew_window_captains_actions_renounce_title_tooltip=你将不再是船长,这个角色将被传递,直到有船员接任。
gui_crew_window_captains_actions_pass_title=将船长传给
gui_crew_window_captains_actions_pass_title_tooltip=让此船员成为船长。
gui_crew_window_captains_actions_plank=跳甲板 (放逐为观众)
gui_crew_window_captains_actions_plank_tooltip=玩家将被送回大厅,暂时不能加入你的队伍。 (或使用 /plank {玩家的名字})
gui_crew_window_captains_actions_make_officer=任命军官
gui_crew_window_captains_actions_make_officer_tooltip=任命此玩家为军官 (或使用/officer {玩家的名字})
gui_crew_window_captains_actions_unmake_officer=解除军官
gui_crew_window_captains_actions_unmake_officer_tooltip=解除此玩家军官职务 或使用 /officer {玩家的名字})
gui_crew_window_captains_actions_revoke_class=撤销职业
gui_crew_window_captains_actions_revoke_class_tooltip=将此玩家的职业放回备用池中。
gui_crew_window_captains_actions_summon_crew=召唤船员上船
gui_crew_window_captains_actions_summon_crew_tooltip=将船员传送回船上
gui_crew_window_captains_actions_tax=征税
gui_crew_window_captains_actions_tax_tooltip=对于团队中的每个非军官,征收__1__%的达布隆(和其他游戏关键物品)。 (或使用 /tax)
gui_crew_window_captains_actions_undock_tip=想要提前出坞,请使用顶部工具栏。
gui_crew_window_crew_age=时长: __1__
gui_crew_window_crew_capacity_and_difficulty=__1__, 容量 __2__.
gui_crew_window_crew_count=船员 (__1__)
gui_evo_tooltip_1=本地虫族进化值: __1__
gui_evo_tooltip_2=里格数: __1__
gui_evo_tooltip_3=海妖: __1__
gui_evo_tooltip_4=时间: __1__
gui_evo_tooltip_5=发射井: __1__
gui_evo_tooltip_6=虫巢: __1__
gui_evo_tooltip_7=沙虫: __1__
gui_info_info=简介
gui_info_updates=更新
gui_info_tips=提示
gui_info_credits=工作人员
gui_fuel_1=剩余燃料:
gui_minimap_tooltip=左键: 放大\n右键: 缩小\n中键: 缩放窗口
gui_minimap_outside_view=外部视图
gui_minimap_switch_left=自动显示地图 — 开启
gui_minimap_switch_right=关闭
gui_progress=进度
gui_progress_distance_travelled=已航行里程:
gui_progress_leagues=__1__ 里格
gui_progress_current_location=当前位置: __1__
gui_progress_time_of_day=时刻: __1__
gui_runs_play=开始游戏
gui_runs_ongoing_runs=正在进行的队伍
gui_runs_ongoing_runs_helpful_tip=想要加入一个团队,首先在下表选择它
gui_runs_ongoing_runs_spectate=观战
gui_runs_ongoing_runs_join_crew=加入团队
gui_runs_ongoing_runs_return_to_lobby=返回大厅
gui_runs_ongoing_runs_hop_on_board=跳上船。
gui_runs_proposals=提案
gui_runs_proposals_endorse_proposal=批准提案
gui_runs_proposals_retract_endorsement=撤回支持
gui_runs_proposals_abandon_proposal=放弃提案
gui_runs_proposal_maker_run_name=团队名称
gui_runs_proposal_maker_run_name_2=名称
gui_runs_proposal_maker_capacity=容量
gui_runs_proposal_maker_capacity_disabled=此容量设置目前不可用。
gui_runs_proposal_maker_propose=提交
gui_runs_proposal_maker_no_limit=无限制
gui_runs_launch=启航
gui_runs_launch_error_1=聚集更多的海盗的支持。
gui_runs_launch_error_2=服务器上的并发运行数已达到管理员设置的上限。
gui_runs_launch_error_3=无法启动;至少要有一个队伍需要高容量。
gui_runs_launch_error_4=没有可用的单桅帆船。改为加入现有的队伍。
gui_runs_wait_to_join=等待加入... __1__
gui_info_main_tooltip=关于海盗船的提示与更新
gui_crews=团队
gui_crews_main_tooltip=查看正在进行的团队,或创建自己的团队
gui_minimap_main_tooltip=查看外部世界。
gui_etaframe_board_warning=返回船舶
gui_etaframe_board_warning_tooltip=大概是时候登船了...
gui_etaframe_autoundock=自动出坞:
gui_etaframe_arriving_in=正在抵达
gui_etaframe_atsea_waiting=船长—点击这里继续冒险
gui_etaframe_undock=出坞:
gui_etaframe_anytime=随时
gui_etaframe_nest_escape_cost=下一个逃生成本:
gui_etaframe_to_escape_store=想要撤离,需要存储
gui_etaframe_or_store=或存储
gui_etaframe_rocket_requirement_tooltip=发射火箭
gui_etaframe_undock_are_you_sure=出坞—你确定吗?
gui_etaframe_launched=发射:
gui_etaframe_launched_tooltip=这个岛的火箭发射了,这里是奖励。
gui_etaframe_launching=火箭正在发射...
gui_etaframe_charge=充电:
gui_etaframe_charge_tooltip=火箭发射井充电: __1__/__2__ GJ\n\n充满电以发射火箭,同时获得达布隆和燃料。
gui_questframe=岛屿任务:
gui_questframe_fail=失败
gui_questframe_ok=OK
gui_questframe_complete_tooltip=这个岛的任务完成了,这里是奖励。
gui_questframe_time=岛屿任务:限时\n\n在倒计时完成之前发射火箭以获得奖励。
gui_questframe_worms=海岛任务:沙虫\n\n杀死足够多的沙虫以获得奖励。
gui_questframe_find=海岛任务:幽灵\n\n找到幽灵以获得奖励。
gui_questframe_resourceflow=海岛任务:资源滚滚\n\n达到特定物品的生产率以获得奖励。
gui_questframe_resourcecount=海岛任务:物品生产\n\n只需在地图上的任何地方完成这些物品的生产即可获得奖励。
gui_questframe_nodamage=岛屿任务:无伤\n\n发射火箭,并且发射井不受到任何伤害。
gui_crew_tooltip_1=你的团队\n\n执行船员操作,例如选择可用的职业。
gui_crew_tooltip_2=你的团队\n\n你是自由人,所以什么也做不了。
gui_progress_tooltip=进度: __1__ 里格\n\n航行 __2__ 里格取得胜利

View File

@ -113,7 +113,7 @@ local function give_passive_xp(data)
if not validate_player(player) then
return
end
if player.afk_time < 200 then
if player.afk_time < 200 and not RPG.get_last_spell_cast(player) then
if Math2D.bounding_box.contains_point(area, player.position) or player.surface.index == loco_surface.index then
if player.surface.index == loco_surface.index then
PermissionGroups.add_player_to_permission_group(player, 'limited')
@ -135,6 +135,7 @@ local function give_passive_xp(data)
}
rpg[player.index].xp_since_last_floaty_text = 0
rpg[player.index].last_floaty_text = game.tick + visuals_delay
RPG.set_last_spell_cast(player, player.position)
if player.gui.screen[rpg_main_frame] then
local f = player.gui.screen[rpg_main_frame]
local d = Gui.get_data(f)

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Balance = require 'maps.pirates.balance'
@ -5,6 +7,7 @@ local Common = require 'maps.pirates.common'
local CoreData = require 'maps.pirates.coredata'
-- local Utils = require 'maps.pirates.utils_local'
local Math = require 'maps.pirates.math'
local Raffle = require 'maps.pirates.raffle'
local _inspect = require 'utils.inspect'.inspect
-- local Structures = require 'maps.pirates.structures.structures'
@ -124,10 +127,13 @@ function Public.eat_up_fraction_of_all_pollution(surface, fraction_of_global_pol
end
function Public.wave_size_rng() -- random variance in attack sizes
local wave_size_multiplier = 1
local memory = Memory.get_crew_memory()
local wave_percentage_chance = Math.clamp(0, 36, 15 + 7 * memory.floating_pollution/1500) --trying this out
local wave_size_multiplier = 1
local rng1 = Math.random(100)
if rng1 <= 65 then
if rng1 > wave_percentage_chance then
wave_size_multiplier = 0
elseif memory.overworldx > 0 then
local rng2 = Math.random(1000)
@ -212,7 +218,7 @@ function Public.try_rogue_attack()
local group = Public.spawn_group_of_scripted_biters(1/2, 6, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target = Public.generate_side_attack_target(surface, group.position)
if not (target and target.valid) then return end
if (not target) or (not target.valid) then return end
-- group.set_command(Public.attack_target(target))
@ -292,9 +298,9 @@ function Public.create_mail_delivery_biters() --these travel cross-map between b
local surface = game.surfaces[Common.current_destination().surface_name]
local enemy_force_name = memory.enemy_force_name
local spawners = surface.find_entities_filtered{name = 'biter-spawner', force = enemy_force_name}
local spawners = Public.get_valid_spawners(surface)
local try_how_many_groups = Math.min(Math.max(0, (#spawners - 8) / 100), 4)
local try_how_many_groups = Math.clamp(0, 4, (#spawners - 8) / 100)
for i = 1, try_how_many_groups do
if Math.random(2) == 1 then
@ -345,7 +351,7 @@ function Public.spawn_group_of_scripted_biters(fraction_of_floating_pollution, m
local surface = game.surfaces[Common.current_destination().surface_name]
local enemy_force_name = memory.enemy_force_name
local spawner = Public.get_random_spawner(surface)
local spawner = Public.get_random_valid_spawner(surface)
if not spawner then log('no spawner found') return end
local nearby_units_to_bring
@ -532,7 +538,7 @@ function Public.generate_side_attack_target(surface, position)
for index, _ in pairs(entities) do
weights[#weights + 1] = 1 + Math.floor((#entities - index) / 2)
end
return Math.raffle(entities, weights)
return Raffle.raffle(entities, weights)
end
function Public.nearest_target(surface, position)
@ -568,11 +574,47 @@ end
-- return false
-- end
function Public.get_random_spawner(surface)
function Public.get_valid_spawners(surface)
local memory = Memory.get_crew_memory()
local spawners = surface.find_entities_filtered({type = 'unit-spawner', force = memory.enemy_force_name})
if (not spawners) or (not spawners[1]) then return end
local boat_spawners = {}
if memory.enemyboats and #memory.enemyboats > 0 then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if eb.spawner and eb.spawner.valid then
boat_spawners[#boat_spawners + 1] = eb.spawner
end
end
end
local valid_spawners = {}
for i = 1, #spawners do
local s = spawners[i]
local valid = true
for j = 1, #boat_spawners do
local bs = boat_spawners[j]
if s == bs then
valid = false
break
end
end
if valid then
valid_spawners[#valid_spawners + 1] = s
end
end
return valid_spawners
end
function Public.get_random_valid_spawner(surface)
local spawners = Public.get_valid_spawners(surface)
if #spawners == 0 then return end
return spawners[Math.random(#spawners)]
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Balance = require 'maps.pirates.balance'
@ -32,7 +34,7 @@ local Task = require 'utils.task'
local Token = require 'utils.token'
local Classes = require 'maps.pirates.roles.classes'
-- local Server = require 'utils.server'
local Server = require 'utils.server'
-- local Modifers = require 'player_modifiers'
local tick_tack_trap = require 'maps.pirates.locally_maintained_comfy_forks.tick_tack_trap' --'enemy' force, but that's okay
@ -54,11 +56,11 @@ function Public.silo_die()
if CoreData.rocket_silo_death_causes_loss then
-- Crew.lose_life()
Crew.try_lose('silo destroyed')
Crew.try_lose({'pirates.loss_silo_destroyed'})
elseif (not destination.dynamic_data.rocketlaunched) and destination.static_params and destination.static_params.base_cost_to_undock and destination.static_params.base_cost_to_undock['launch_rocket'] and destination.static_params.base_cost_to_undock['launch_rocket'] == true then
Crew.try_lose('silo destroyed before a necessary launch')
Crew.try_lose({'pirates.loss_silo_destroyed_before_necessary_launch'})
elseif (not destination.dynamic_data.rocketlaunched) then
Common.notify_force(force, 'The silo was destroyed.')
Common.notify_force(force, {'pirates.silo_destroyed'})
end
end
@ -208,7 +210,7 @@ local function damage_to_artillery(event)
-- remove resistances:
-- event.entity.health = event.entity.health + event.final_damage_amount - event.original_damage_amount
if Common.entity_damage_healthbar(event.entity, event.original_damage_amount / 1.5 * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness)), Memory.get_crew_memory().boat) <= 0 then
if Common.entity_damage_healthbar(event.entity, event.original_damage_amount / Balance.cannon_resistance_factor * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness)), Memory.get_crew_memory().boat) <= 0 then
event.entity.die()
end
else
@ -251,7 +253,7 @@ local function damage_to_krakens(event)
end
if event.damage_type.name and (event.damage_type.name == 'laser') then
adjusted_damage = adjusted_damage / 8 --laser turrets are in range
adjusted_damage = adjusted_damage / 7 --laser turrets are in range. give some resistance
end
if Common.entity_damage_healthbar(event.entity, adjusted_damage) <= 0 then
@ -276,23 +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
damage_multiplier = damage_multiplier * 1.5
--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
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 * 0.25
elseif class and class == Classes.enum.HATAMOTO then --lethal damage needs to be unaffected
damage_multiplier = damage_multiplier * 0.16
elseif class and class == Classes.enum.IRON_LEG then --lethal damage needs to be unaffected
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 >= 3500 then
damage_multiplier = damage_multiplier * 0.18
damage_multiplier = damage_multiplier * Balance.samurai_damage_taken_multiplier
elseif class and class == Classes.enum.HATAMOTO then
damage_multiplier = damage_multiplier * Balance.hatamoto_damage_taken_multiplier
elseif class and class == Classes.enum.IRON_LEG then
if memory.class_auxiliary_data[player_index] and memory.class_auxiliary_data[player_index].iron_leg_active then
damage_multiplier = damage_multiplier * Balance.iron_leg_damage_taken_multiplier
end
-- else
-- damage_multiplier = damage_multiplier * (1 + Balance.bonus_damage_to_humans())
@ -306,9 +307,28 @@ local function damage_to_players_changes(event)
if damage_multiplier > 1 then
event.entity.health = event.entity.health - event.final_damage_amount * (damage_multiplier - 1)
elseif damage_multiplier < 1 and event.final_health > 0 then --lethal damage needs to be unaffected, else they never die
elseif damage_multiplier < 1 and event.final_health > 0 then --lethal damage case isn't this easy
event.entity.health = event.entity.health + event.final_damage_amount * (1 - damage_multiplier)
end
-- deal with damage reduction on lethal damage for players
-- Piratux wrote this code — it tracks player health (except passive regen), and intervenes on a lethal damage event, so it should work most of the time.
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
@ -352,7 +372,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
@ -368,19 +388,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 * extra_physical_damage_from_research_multiplier
elseif hatamoto then
extra_damage_to_deal = 50
extra_damage_to_deal = Balance.hatamoto_damage_dealt_with_melee * 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
@ -401,13 +425,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
@ -599,7 +623,7 @@ end
function Public.load_some_map_chunks_random_order(destination_index, fraction)
function Public.load_some_map_chunks_random_order(destination_index, fraction) -- The reason we might want to do this is because of algorithms like the labyrinth code, which make directionally biased patterns if you don't generate chunks in a random order
local memory = Memory.get_crew_memory()
local destination_data = memory.destinations[destination_index]
@ -645,21 +669,21 @@ 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()
-- 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
-- -- 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
@ -678,8 +702,6 @@ local function event_on_player_mined_entity(event)
return
end
local every_nth_tree_gives_coins = 6
if entity.type == 'tree' then
if not event.buffer then return end
local available = destination.dynamic_data.wood_remaining
@ -688,7 +710,7 @@ local function event_on_player_mined_entity(event)
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, 35) == 1 then
if Math.random(1, 38) == 1 then
tick_tack_trap(memory.enemy_force_name, entity.surface, entity.position)
return
end
@ -696,22 +718,18 @@ local function event_on_player_mined_entity(event)
local give = {}
if memory.classes_table and memory.classes_table[event.player_index] then
if memory.classes_table[event.player_index] == Classes.enum.LUMBERJACK then
give[#give + 1] = {name = 'wood', count = 4}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 20
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
end
elseif memory.classes_table[event.player_index] == Classes.enum.WOOD_LORD then
give[#give + 1] = {name = 'wood', count = 1}
give[#give + 1] = {name = 'iron-ore', count = 1}
give[#give + 1] = {name = 'copper-ore', count = 1}
give[#give + 1] = {name = 'coal', count = 1}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 12
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
end
Classes.lumberjack_bonus_items(give)
-- elseif memory.classes_table[event.player_index] == Classes.enum.WOOD_LORD then
-- give[#give + 1] = {name = 'wood', count = 1}
-- give[#give + 1] = {name = 'iron-ore', count = 1}
-- give[#give + 1] = {name = 'copper-ore', count = 1}
-- give[#give + 1] = {name = 'coal', count = 1}
-- if Math.random(every_nth_tree_gives_coins) == 1 then
-- local a = 12
-- 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
-- end
end
end
@ -723,29 +741,26 @@ local function event_on_player_mined_entity(event)
local baseamount = 4
--minimum 1 wood
local amount = Math.max(Math.ceil(Math.min(available, baseamount * available/starting)),1)
local amount = Math.clamp(1, Math.max(1, Math.ceil(available)), Math.ceil(baseamount * available/starting))
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 + 3}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 12
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
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 + 3}
give[#give + 1] = {name = 'iron-ore', count = 1}
give[#give + 1] = {name = 'copper-ore', count = 1}
give[#give + 1] = {name = 'coal', count = 1}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 12
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
end
give[#give + 1] = {name = 'wood', count = amount}
Classes.lumberjack_bonus_items(give)
-- 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 + 3}
-- give[#give + 1] = {name = 'iron-ore', count = 1}
-- give[#give + 1] = {name = 'copper-ore', count = 1}
-- give[#give + 1] = {name = 'coal', count = 1}
-- if Math.random(every_nth_tree_gives_coins) == 1 then
-- local a = 12
-- 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
-- end
else
give[#give + 1] = {name = 'wood', count = amount}
if Math.random(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
@ -762,13 +777,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()
@ -778,7 +793,7 @@ local function event_on_player_mined_entity(event)
local give = {}
if memory.overworldx > 0 then
if memory.overworldx > 0 then --no coins on first map, else the optimal strategy is to handmine everything there
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.PROSPECTOR then
local a = 3
give[#give + 1] = {name = 'coin', count = a}
@ -896,11 +911,11 @@ local function base_kill_rewards(event)
if entity_name == 'small-worm-turret' then
iron_amount = 5
coin_amount = 60
coin_amount = 50
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'medium-worm-turret' then
iron_amount = 20
coin_amount = 100
coin_amount = 90
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'biter-spawner' or entity_name == 'spitter-spawner' then
iron_amount = 30
@ -908,11 +923,11 @@ local function base_kill_rewards(event)
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'big-worm-turret' then
iron_amount = 30
coin_amount = 160
coin_amount = 140
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'behemoth-worm-turret' then
iron_amount = 50
coin_amount = 280
coin_amount = 260
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif memory.overworldx > 0 then --avoid coin farming on first island
if entity_name == 'small-biter' then
@ -953,13 +968,15 @@ local function base_kill_rewards(event)
stack = {{name = 'coin', count = coin_amount}}
end
local short_form = (not iron_amount) and true or false
if revenge_target then
Common.give(revenge_target.player, stack, revenge_target.player.position, entity.surface, entity.position)
Common.give(revenge_target.player, stack, revenge_target.player.position, short_form, entity.surface, entity.position)
else
if event.cause and event.cause.valid and event.cause.position then
Common.give(nil, stack, event.cause.position, entity.surface, entity.position)
Common.give(nil, stack, event.cause.position, short_form, entity.surface, entity.position)
else
Common.give(nil, stack, entity.position, entity.surface)
Common.give(nil, stack, entity.position, short_form, entity.surface)
end
end
end
@ -1045,7 +1062,7 @@ local function event_on_entity_died(event)
-- if memory.boat.cannonscount <= 0 then
-- Crew.try_lose()
-- end
Crew.try_lose('cannon destroyed')
Crew.try_lose({'pirates.loss_cannon_destroyed'})
end
end
@ -1114,7 +1131,7 @@ local function event_on_research_finished(event)
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)
memory.force.print({"", '>> ', {'pirates.research_notification', event.research.localised_name}}, CoreData.colors.notify_force_light)
Public.apply_flamer_nerfs()
-- Public.research_apply_buffs(event) -- this is broken right now
@ -1180,6 +1197,14 @@ local function event_on_player_joined_game(event)
--figure out if we should drop them back into a crew:
if (not Server.get_current_time()) then -- don't run this on servers because I'd need to negotiate that with the rest of Comfy
player.print({'pirates.thesixthroc_support_toast'}, {r=1, g=0.4, b=0.9})
end
if _DEBUG then
game.print('Debug mode on. Use /go to get started, /1 /4 /32 etc to change game speed.')
end
local crew_to_put_back_in = nil
for _, mem in pairs(global_memory.crew_memories) do
if mem.id and mem.crewstatus and mem.crewstatus == Crew.enum.ADVENTURING and mem.temporarily_logged_off_characters[player.index] then
@ -1191,6 +1216,11 @@ local function event_on_player_joined_game(event)
if crew_to_put_back_in then
Crew.join_crew(player, crew_to_put_back_in, true)
local memory = global_memory.crew_memories[crew_to_put_back_in]
if #memory.crewplayerindices <= 1 then
memory.playerindex_captain = player.index
end
if _DEBUG then log('putting player back in their old crew') end
else
if player.character and player.character.valid then
@ -1234,11 +1264,17 @@ local function event_on_player_joined_game(event)
)
if ages[1] then
Crew.join_crew(player, ages[1].id)
local memory = global_memory.crew_memories[ages[1].id]
if #memory.crewplayerindices <= 1 then
memory.playerindex_captain = player.index
end
if ages[2] then
if ages[1].large and (not ages[#ages].large) then
Common.notify_player_announce(player, 'There are multiple crews on this server. You have been placed in the oldest crew with large capacity.')
Common.notify_player_announce(player, {'pirates.goto_oldest_crew_with_large_capacity'})
else
Common.notify_player_announce(player, 'There are multiple crews on this server. You have been placed in the oldest.')
Common.notify_player_announce(player, {'pirates.goto_oldest_crew'})
end
end
end
@ -1248,6 +1284,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})
@ -1317,6 +1355,8 @@ local function event_on_pre_player_left_game(event)
break
end
end
global_memory.last_players_health[event.player_index] = nil
end
@ -1604,13 +1644,13 @@ local function event_on_rocket_launched(event)
if memory.stored_fuel and destination.dynamic_data and destination.dynamic_data.rocketcoalreward then
memory.stored_fuel = memory.stored_fuel + destination.dynamic_data.rocketcoalreward
local a = Balance.rocket_launch_coin_reward
Common.give_items_to_crew({{name = 'coin', count = a}}, true)
Common.give_items_to_crew({{name = 'coin', count = a}})
memory.playtesting_stats.coins_gained_by_rocket_launches = memory.playtesting_stats.coins_gained_by_rocket_launches + a
end
local force = memory.force
Common.notify_force_light(force,'Granted: ' .. Math.floor(Balance.rocket_launch_coin_reward/100)/10 .. 'k [item=coin], ' .. Math.floor(destination.dynamic_data.rocketcoalreward/100)/10 .. 'k [item=coal].')
local message = {'pirates.granted_2', {'pirates.granted_rocket_launch'}, Math.floor(Balance.rocket_launch_coin_reward/100)/10 .. 'k [item=coin]', Math.floor(destination.dynamic_data.rocketcoalreward/100)/10 .. 'k [item=coal]'}
Common.notify_force_light(force,message)
if destination.dynamic_data.quest_type == Quest.enum.TIME and (not destination.dynamic_data.quest_complete) then
destination.dynamic_data.quest_progressneeded = 1
@ -1621,6 +1661,16 @@ local function event_on_rocket_launched(event)
destination.dynamic_data.quest_progress = destination.dynamic_data.rocketsilohp
Quest.try_resolve_quest()
end
if destination.dynamic_data.rocketsilos then
for i = 1, #destination.dynamic_data.rocketsilos do
local s = destination.dynamic_data.rocketsilos[i]
if s and s.valid then
s.die()
end
end
destination.dynamic_data.rocketsilos = nil
end
end
@ -1649,7 +1699,7 @@ local function event_on_built_entity(event)
player.insert{name = entity.name, count = 1}
end
entity.destroy()
Common.notify_player_error(player, 'Build error: Undergrounds can\'t be built on the boat, due to conflicts with the boat movement code.')
Common.notify_player_error(player, {'pirates.error_build_undergrounds_on_boat'})
return
end
end
@ -1726,7 +1776,7 @@ local remove_boost_movement_speed_on_respawn =
if memory.game_lost then return end
memory.speed_boost_characters[player.index] = nil
Common.notify_player_expected(player, 'Respawn speed bonus removed.')
Common.notify_player_expected(player, {'pirates.respawn_speed_bonus_removed'})
end
)
@ -1747,7 +1797,7 @@ local boost_movement_speed_on_respawn =
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.')
Common.notify_player_expected(player, {'pirates.respawn_speed_bonus_applied'})
end
)
@ -1762,7 +1812,7 @@ local function event_on_player_respawned(event)
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
if boat and boat.state == Boats.enum_state.ATSEA_SAILING or boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL or boat.state == Boats.enum_state.ATSEA_LOADING_MAP then
-- assuming sea is always default:
local seasurface = game.surfaces[memory.sea_name]
player.teleport(memory.spawnpoint, seasurface)
@ -1770,6 +1820,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
@ -1784,14 +1837,14 @@ event.add(defines.events.on_entity_died, event_on_entity_died)
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_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_chunk_generated, PiratesApiEvents.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)

View File

@ -1,3 +1,5 @@
-- 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...
@ -9,9 +11,8 @@ local Boats = require 'maps.pirates.structures.boats.boats'
local Islands = require 'maps.pirates.surfaces.islands.islands'
local IslandsCommon = require 'maps.pirates.surfaces.islands.common'
local Surfaces = require 'maps.pirates.surfaces.surfaces'
local Interface = require 'maps.pirates.interface'
local PiratesApiEvents = require 'maps.pirates.api_events'
local Roles = require 'maps.pirates.roles.roles'
local Classes = require 'maps.pirates.roles.classes'
local Progression = require 'maps.pirates.progression'
local Crowsnest = require 'maps.pirates.surfaces.crowsnest'
local Hold = require 'maps.pirates.surfaces.hold'
@ -28,9 +29,8 @@ local _inspect = require 'utils.inspect'.inspect
local Kraken = require 'maps.pirates.surfaces.sea.kraken'
local Quest = require 'maps.pirates.quest'
local Loot = require 'maps.pirates.loot'
local ShopDock = require 'maps.pirates.shop.dock'
local ShopCovered = require 'maps.pirates.shop.covered'
local QuestStructures = require 'maps.pirates.structures.quest_structures.quest_structures'
local Public = {}
@ -71,7 +71,7 @@ function Public.prevent_unbarreling_off_ship(tickinterval)
local r = a.get_recipe()
if r and r.subgroup and r.subgroup.name and r.subgroup.name == 'fill-barrel' and (not (r.name and r.name == 'fill-water-barrel')) then
if not Boats.on_boat(boat, a.position) then
Common.notify_force_error(memory.force, 'Recipe error: Barrels are too heavy to carry back to the ship. Try another way.')
Common.notify_force_error(memory.force, {'pirates.error_cant_carry_barrels'})
a.set_recipe('fill-water-barrel')
end
end
@ -98,7 +98,7 @@ function Public.prevent_disembark(tickinterval)
for _, player in pairs(game.connected_players) do
if player.surface and player.surface.valid and boat.surface_name and player.surface.name == boat.surface_name and ps[player.index] and (not Boats.on_boat(boat, player.position)) and (not (player.controller_type == defines.controllers.spectator)) then
Common.notify_player_error(player, 'Now is no time to disembark.')
Common.notify_player_error(player, {'pirates.error_disembark'})
-- player.teleport(memory.spawnpoint)
local p = player.surface.find_non_colliding_position('character', memory.spawnpoint, 5, 0.1)
if p then
@ -124,7 +124,7 @@ function Public.check_all_spawners_dead(tickinterval)
local spawnerscount = Common.spawner_count(surface)
if spawnerscount == 0 then
destination.static_params.base_cost_to_undock = nil
Common.notify_force(memory.force, 'All biter bases destroyed — escape cost removed.')
Common.notify_force(memory.force, {'pirates.destroyed_all_nests'})
end
end
end
@ -182,11 +182,11 @@ function Public.ship_deplete_fuel(tickinterval)
if rate < 0 and memory.stored_fuel < 1000 and (not (memory.parrot_fuel_most_recent_warning and memory.parrot_fuel_most_recent_warning >= game.tick - 60*60*12)) then --12 minutes
memory.parrot_fuel_most_recent_warning = game.tick
Common.parrot_speak(memory.force, 'Fuel is low!')
Common.parrot_speak(memory.force, {'pirates.parrot_fuel_warning'})
end
if memory.stored_fuel < 0 then
Crew.try_lose('out of fuel')
Crew.try_lose({'pirates.loss_out_of_fuel'})
end
end
@ -220,7 +220,7 @@ function Public.captain_warn_afk(tickinterval)
if memory.playerindex_captain then
for _, player in pairs(game.connected_players) do
if Common.is_captain(player) and #Common.crew_get_nonafk_crew_members() > 1 and player.afk_time >= Common.afk_time - 20*60 - 60 - tickinterval and player.afk_time < Common.afk_time - 20*60 then
Common.notify_player_announce(player, 'Note: If you go idle as captain for too long, the role passes to another crewmember.')
Common.notify_player_announce(player, {'pirates.warn_nearly_afk_captain'})
player.play_sound{path = 'utility/scenario_message'}
end
end
@ -258,7 +258,7 @@ function Public.prune_offline_characters_list(tickinterval)
end
end
if any then
Common.notify_force_light(memory.force, 'Offline player\'s items recovered to cabin.')
Common.notify_force_light(memory.force, {'pirates.recover_offline_player_items'})
end
for ii = 1, 5, 1 do
if player_inv[ii].valid then
@ -286,7 +286,8 @@ function Public.periodic_free_resources(tickinterval)
Common.give_items_to_crew{{name = 'sulfuric-acid-barrel', count = count}}
local force = memory.force
if not (force and force.valid) then return end
Common.notify_force_light(force, 'Granted: ' .. count .. ' [item=sulfuric-acid-barrel]')
local message = {'pirates.granted_1', {'pirates.granted_periodic_barrel'}, count .. ' [item=sulfuric-acid-barrel]'}
Common.notify_force_light(force, message)
end
end
@ -339,7 +340,7 @@ function Public.pick_up_tick(tickinterval)
map.state = 'picked_up'
rendering.destroy(map.mapobject_rendering)
Common.notify_force_light(player.force, player.name .. ' found a map. Treasure location revealed.')
Common.notify_force_light(player.force, {'pirates.find_map',player.name})
map.x_renderings = {
rendering.draw_line{
@ -396,7 +397,7 @@ function Public.pick_up_tick(tickinterval)
ghost.state = 'picked_up'
Common.notify_force(player.force, player.name .. ' found a ghost.')
Common.notify_force(player.force, {'pirates.find_ghost',player.name})
dynamic_data.quest_progress = dynamic_data.quest_progress + 1
Quest.try_resolve_quest()
@ -412,7 +413,7 @@ local function cached_structure_delete_existing_entities_if_needed(surface, posi
local area = {left_top = {position.x - special.width/2, position.y - special.height/2}, right_bottom = {position.x + special.width/2 + 0.5, position.y + special.height/2 + 0.5}}
surface.destroy_decoratives{area=area}
local existing = surface.find_entities_filtered{area = area}
if existing and (not (special.name == 'covered1b')) then
if existing then
for _, e in pairs(existing) do
if not (((special.name == 'small_primitive_mining_base' or special.name == 'small_mining_base') and (e.name == 'iron-ore' or e.name == 'copper-ore' or e.name == 'stone')) or (special.name == 'uranium_miners' and e.name == 'uranium-ore')) then
if not (e.name and e.name == 'rocket-silo') then
@ -442,6 +443,8 @@ function Public.interpret_shorthanded_force_name(shorthanded_name)
return ret
end
function Public.place_cached_structures(tickinterval)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
@ -449,6 +452,11 @@ function Public.place_cached_structures(tickinterval)
if (not destination.dynamic_data) or (not destination.dynamic_data.structures_waiting_to_be_placed) or (not surface_name) or (not game.surfaces[surface_name]) or (not game.surfaces[surface_name].valid) then return end
if not (memory.boat and memory.boat.surface_name and memory.boat.surface_name == surface_name) then
return --We only want to generate structures once the players arrive on the island. Otherwise, the following issue happens. 2x2 structures force-generate nearby chunks. But if the island has many structures, that could cause a domino effect of chunk-generation, lagging the game.
-- Since this change, this function has little conceptual reason to be an on_tick function, but it makes sense to run it a few ticks after you teleport to the island, so it can stay one for now.
end
local surface = game.surfaces[surface_name]
local structures = destination.dynamic_data.structures_waiting_to_be_placed
@ -460,7 +468,7 @@ function Public.place_cached_structures(tickinterval)
local special = structure.data
local position = special.position
Common.ensure_chunks_at(surface, position, 2)
Common.ensure_chunks_at(surface, position, Common.structure_ensure_chunk_radius)
cached_structure_delete_existing_entities_if_needed(surface, position, special)
@ -576,118 +584,10 @@ function Public.place_cached_structures(tickinterval)
saved_components[#saved_components + 1] = c2
end
end
Structures.post_creation_process(special.name, saved_components)
if special.name == 'covered1' then
local covered_data = destination.dynamic_data.covered_data
if not covered_data then return end
local hardcoded_data = Structures.IslandStructures.ROC.covered1.Data
covered_data.blue_chest = surface.create_entity{name = 'blue-chest', position = Math.vector_sum(special.position, hardcoded_data.blue_chest), force = 'environment'}
if covered_data.blue_chest and covered_data.blue_chest.valid then
covered_data.blue_chest.minable = false
covered_data.blue_chest.rotatable = false
covered_data.blue_chest.operable = false
covered_data.blue_chest.destructible = false
end
covered_data.red_chest = surface.create_entity{name = 'red-chest', position = Math.vector_sum(special.position, hardcoded_data.red_chest), force = 'environment'}
if covered_data.red_chest and covered_data.red_chest.valid then
covered_data.red_chest.minable = false
covered_data.red_chest.rotatable = false
covered_data.red_chest.operable = false
covered_data.red_chest.destructible = false
end
covered_data.door_walls = {}
for _, p in pairs(hardcoded_data.walls) do
local e = surface.create_entity{name = 'stone-wall', position = Math.vector_sum(special.position, p), force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
e.operable = false
e.destructible = false
end
covered_data.door_walls[#covered_data.door_walls + 1] = e
end
elseif special.name == 'covered1b' then
local covered_data = destination.dynamic_data.covered_data
if not covered_data then return end
local hardcoded_data = Structures.IslandStructures.ROC.covered1b.Data
covered_data.market = surface.create_entity{name = 'market', position = Math.vector_sum(special.position, hardcoded_data.market), force = string.format('ancient-friendly-%03d', memory.id)}
if covered_data.market and covered_data.market.valid then
covered_data.market.minable = false
covered_data.market.rotatable = false
covered_data.market.destructible = false
covered_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = Balance.coin_sell_amount}}
covered_data.market.add_market_item{price={{'burner-mining-drill', 1}}, offer={type = 'give-item', item = 'iron-plate', count = 9}}
local how_many_coin_offers = 4
if Balance.crew_scale() >= 1.2 then how_many_coin_offers = 5 end
local coin_offers = ShopCovered.market_generate_coin_offers(how_many_coin_offers)
for _, o in pairs(coin_offers) do
covered_data.market.add_market_item(o)
end
if destination.static_params.class_for_sale then
covered_data.market.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing", effect_description = 'Purchase the class ' .. Classes.display_form[destination.static_params.class_for_sale] .. '.'}}
-- destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
-- text = 'Class available: ' .. Classes.display_form[destination.static_params.class_for_sale],
-- surface = surface,
-- target = Utils.psum{special.position, hardcoded_data.market, {x = 1, y = -3.9}},
-- color = CoreData.colors.renderingtext_green,
-- scale = 2.5,
-- font = 'default-game',
-- alignment = 'center'
-- }
end
end
covered_data.steel_chest = surface.create_entity{name = 'steel-chest', position = Math.vector_sum(special.position, hardcoded_data.steel_chest), force = string.format('ancient-friendly-%03d', memory.id)}
if covered_data.steel_chest and covered_data.steel_chest.valid then
covered_data.steel_chest.minable = false
covered_data.steel_chest.rotatable = false
covered_data.steel_chest.destructible = false
local inv = covered_data.steel_chest.get_inventory(defines.inventory.chest)
local loot = destination.dynamic_data.covered1_requirement.raw_materials
for j = 1, #loot do
local l = loot[j]
if l.count > 0 then
inv.insert(l)
end
end
end
for _, w in pairs(covered_data.door_walls) do
w.destructible = true
w.destroy()
end
covered_data.wooden_chests = {}
for k, p in ipairs(hardcoded_data.wooden_chests) do
local e = surface.create_entity{name = 'wooden-chest', position = Math.vector_sum(special.position, p), 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.covered_wooden_chest_loot()
if k==1 then loot[1] = {name = 'coin', count = 2000} end
for j = 1, #loot do
local l = loot[j]
inv.insert(l)
end
end
covered_data.wooden_chests[#covered_data.wooden_chests + 1] = e
end
end
Structures.configure_structure_entities(special.name, saved_components)
QuestStructures.create_quest_structure_entities(special.name)
for j = i, #structures-1 do
structures[j] = structures[j+1]
@ -697,61 +597,7 @@ function Public.place_cached_structures(tickinterval)
end
end
function Public.covered_requirement_check(tickinterval)
local memory = Memory.get_crew_memory()
if memory.game_lost then return end
local destination = Common.current_destination()
if not (destination and destination.dynamic_data) then return end
local covered_data = destination.dynamic_data.covered_data
if not covered_data then return end
local blue_chest = covered_data.blue_chest
local red_chest = covered_data.red_chest
if not (blue_chest and blue_chest.valid and red_chest and red_chest.valid) then return end
local blue_inv = covered_data.blue_chest.get_inventory(defines.inventory.chest)
local red_inv = covered_data.red_chest.get_inventory(defines.inventory.chest)
local blue_contents = blue_inv.get_contents()
local requirement = covered_data.requirement
local got = 0
for k, v in pairs(blue_contents) do
if covered_data.state == 'covered' and k == requirement.name then
got = v
else
-- @FIX: power armor loses components, items lose health!
red_inv.insert({name = k, count = v});
blue_inv.remove({name = k, count = v});
end
end
if covered_data.state == 'covered' then
if got >= requirement.count then
blue_inv.remove({name = requirement.name, count = requirement.count});
covered_data.state = 'uncovered'
rendering.destroy(covered_data.rendering1)
rendering.destroy(covered_data.rendering2)
local structureData = Structures.IslandStructures.ROC.covered1b.Data
local special = {
position = covered_data.position,
components = structureData.components,
width = structureData.width,
height = structureData.height,
name = structureData.name,
}
destination.dynamic_data.structures_waiting_to_be_placed[#destination.dynamic_data.structures_waiting_to_be_placed + 1] = {data = special, tick = game.tick}
else
if covered_data.rendering1 then
rendering.set_text(covered_data.rendering1, 'Needs ' .. requirement.count - got .. ' x')
end
end
else
end
end
@ -992,7 +838,7 @@ function Public.loading_update(tickinterval)
if memory.loadingticks >= 350 - Common.loading_interval then
if Boats.players_on_boat_count(memory.boat) > 0 then
if memory.loadingticks < 350 then
Common.notify_game('[' .. memory.name .. '] Loading new game...')
Common.notify_game({'', '[' .. memory.name .. '] ', {'pirates.loading_new_game'}})
elseif memory.loadingticks > 410 then
if not Crowsnest.get_crowsnest_surface() then
Crew.initialise_crowsnest_1()
@ -1000,7 +846,7 @@ function Public.loading_update(tickinterval)
Crew.initialise_crowsnest_2()
Overworld.ensure_lane_generated_up_to(0, 10)
Surfaces.create_surface(memory.destinations[destination_index])
-- Interface.load_some_map_chunks(destination_index, 0.02)
-- PiratesApiEvents.load_some_map_chunks(destination_index, 0.02)
end
end
else
@ -1042,7 +888,7 @@ function Public.loading_update(tickinterval)
if Boats.players_on_boat_count(memory.boat) > 0 then
local fraction = 0.07 + 0.7 * (memory.loadingticks - 860) / 400
Interface.load_some_map_chunks(destination_index, fraction)
PiratesApiEvents.load_some_map_chunks(destination_index, fraction)
else
Boats.destroy_boat(memory.boat)
Crew.disband_crew()
@ -1059,7 +905,7 @@ function Public.loading_update(tickinterval)
-- elseif memory.loadingticks <= 500 and memory.loadingticks >= 100 then
-- local fraction = 0.02 + 0.05 * (memory.loadingticks - 100) / 400
-- Interface.load_some_map_chunks(destination_index, fraction)
-- PiratesApiEvents.load_some_map_chunks(destination_index, fraction)
end
elseif memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP then
@ -1073,31 +919,31 @@ function Public.loading_update(tickinterval)
local eta_ticks = total - (memory.loadingticks - (memory.extra_time_at_sea or 0))
-- log(_inspect{eta_ticks, (memory.active_sea_enemies.krakens and #memory.active_sea_enemies.krakens or 'nil'), memory.loadingticks})
if eta_ticks < 60*20 and memory.active_sea_enemies and (memory.active_sea_enemies.krakens and #memory.active_sea_enemies.krakens > 0) then
memory.loadingticks = memory.loadingticks - tickinterval
memory.loadingticks = memory.loadingticks - tickinterval --reverse the change
else
local fraction = memory.loadingticks / (total + (memory.extra_time_at_sea or 0))
if fraction > Common.fraction_of_map_loaded_atsea then
if fraction > Common.fraction_of_map_loaded_at_sea then
Progression.progress_to_destination(destination_index)
memory.loadingticks = 0
else
Interface.load_some_map_chunks_random_order(destination_index, fraction) --random order is good for maze world
PiratesApiEvents.load_some_map_chunks_random_order(destination_index, fraction) --random order is good for maze world
end
end
elseif memory.boat.state == Boats.enum_state.LANDED then
local fraction = Common.fraction_of_map_loaded_atsea + (1 - Common.fraction_of_map_loaded_atsea) * memory.loadingticks / Common.map_loading_ticks_onisland
local fraction = Common.fraction_of_map_loaded_at_sea + (1 - Common.fraction_of_map_loaded_at_sea) * memory.loadingticks / Common.map_loading_ticks_onisland
if fraction > 1 then
memory.loadingticks = nil
else
Interface.load_some_map_chunks(destination_index, fraction)
PiratesApiEvents.load_some_map_chunks(destination_index, fraction)
end
end
end
end
@ -1120,14 +966,14 @@ function Public.crowsnest_steer(tickinterval)
if count_left >= 100 and count_right < 100 and memory.overworldy > -24 then
if Overworld.try_overworld_move_v2{x = 0, y = -24} then
local force = memory.force
Common.notify_force(force, 'Steering portside...')
Common.notify_force(force, {'pirates.steer_left'})
inv_left.remove({name = "rail-signal", count = 100})
end
return
elseif count_right >= 100 and count_left < 100 and memory.overworldy < 24 then
if Overworld.try_overworld_move_v2{x = 0, y = 24} then
local force = memory.force
Common.notify_force(force, 'Steering starboard...')
Common.notify_force(force, {'pirates.steer_right'})
inv_right.remove({name = "rail-signal", count = 100})
end
return
@ -1176,13 +1022,16 @@ function Public.silo_update(tickinterval)
game.pollution_statistics.on_flow('rocket-silo', pollution)
if not memory.floating_pollution then memory.floating_pollution = 0 end
-- Eventually I want to reformulate pollution not to pull from the map directly, but to pull from pollution_statistics. Previously all the silo pollution went to the map, but this causes a lag ~1-2 minutes. So as a compromise, let's send half to floating_pollution directly, and half to the map:
memory.floating_pollution = memory.floating_pollution + pollution/2
game.surfaces[destination.surface_name].pollute(p, pollution/2)
-- Eventually I want to reformulate pollution not to pull from the map directly, but to pull from pollution_statistics. Previously all the silo pollution went to the map, but this causes a lag ~1-2 minutes. So as a compromise, let's send some to floating_pollution directly, and some to the map:
memory.floating_pollution = memory.floating_pollution + 3*pollution/4
game.surfaces[destination.surface_name].pollute(p, pollution/4)
if memory.overworldx >= 80 and dynamic_data.rocketsiloenergyconsumed >= 0.25 * dynamic_data.rocketsiloenergyneeded and (not dynamic_data.parrot_silo_warned) then
if memory.overworldx >= 0 and dynamic_data.rocketsiloenergyconsumed >= 0.25 * dynamic_data.rocketsiloenergyneeded and (not dynamic_data.parrot_silo_warned) then
dynamic_data.parrot_silo_warned = true
Common.parrot_speak(memory.force, 'The silo is attracting biters...')
local spawnerscount = Common.spawner_count(game.surfaces[destination.surface_name])
if spawnerscount > 0 then
Common.parrot_speak(memory.force, {'pirates.parrot_silo_warning'})
end
elseif dynamic_data.rocketsiloenergyconsumed >= dynamic_data.rocketsiloenergyneeded and (not (silo.rocket_parts == 100)) and (dynamic_data.silocharged == false) and (not memory.game_lost) then
-- silo.energy = 0
silo.rocket_parts = 100
@ -1288,7 +1137,7 @@ end
-- Delay.move_tasks_to_buffer()
-- end
function Public.Kraken_Destroyed_Backup_check(tickinterval) -- a server became bugged when the kraken spawner entity disappeared but the kraken_die had not fired, and I'm not sure why, so this is a backup checker for that case
function Public.Kraken_Destroyed_Backup_check(tickinterval) -- a server became stuck when the kraken spawner entity disappeared but the kraken_die had not fired, and I'm not sure why, so this is a backup checker for that case
local memory = Memory.get_crew_memory()
local boat = memory.boat
@ -1315,7 +1164,6 @@ function Public.Kraken_Destroyed_Backup_check(tickinterval) -- a server became b
end
end
end
end
end
end

View File

@ -1,18 +1,62 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
local Math = require 'maps.pirates.math'
-- local Raffle = require 'maps.pirates.raffle'
-- local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
local Utils = require 'maps.pirates.utils_local'
-- local Utils = require 'maps.pirates.utils_local'
local _inspect = require 'utils.inspect'.inspect
-- this file is an API to all the balance tuning knobs
Public.base_extra_character_speed = 0.20
Public.base_extra_character_speed = 1.44
Public.respawn_speed_boost = 1.75
Public.cannon_starting_hp = 2000--too low, and crew is too fragile. too high, and the run survives when we should put it out of its misery. But this should go up later in the game.
Public.cannon_resistance_factor = 2
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 = 25
Public.hatamoto_damage_taken_multiplier = 0.16
Public.hatamoto_damage_dealt_when_not_melee_multiplier = 0.75
Public.hatamoto_damage_dealt_with_melee = 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
@ -29,7 +73,7 @@ Public.EEI_stages = { --multipliers
function Public.scripted_biters_pollution_cost_multiplier()
return 1.45 / Math.sloped(Common.difficulty_scale(), 1/5) * (1 + 1.2 / ((1 + (Common.overworldx()/40))^(1.5+Common.difficulty_scale()))) -- the complicated factor just makes the early-game easier; in particular the first island, but on easier difficulties the next few islands as well
return 1.45 / Math.sloped(Common.difficulty_scale(), 1/3) * (1 + 1.2 / ((1 + (Common.overworldx()/40))^(1.5+Common.difficulty_scale()))) -- the complicated factor just makes the early-game easier; in particular the first island, but on easier difficulties the next few islands as well
end
function Public.cost_to_leave_multiplier()
@ -40,8 +84,6 @@ function Public.cost_to_leave_multiplier()
return Math.sloped(Common.difficulty_scale(), 8/10)
end
Public.rocket_launch_coin_reward = 6000
function Public.crew_scale()
local ret = Common.activecrewcount()/10
if ret == 0 then ret = 1/10 end --if all players are afk
@ -78,8 +120,8 @@ end
function Public.silo_count()
local E = Public.silo_energy_needed_MJ()
return Math.ceil(E/(16.8 * 300)) --no more than this many seconds to charge it. Players can in fact go even faster using beacons
-- return Math.ceil(E/(16.8 * 210)) --no more than this many seconds to charge it. Players can in fact go even faster using beacons
return Math.min(Math.ceil(E/(16.8 * 300)),6)
-- return Math.ceil(E/(16.8 * 300)) --no more than this many seconds to charge it. Players can in fact go even faster using beacons
end
@ -177,7 +219,7 @@ function Public.boat_passive_pollution_per_minute(time)
end
return boost * (
2.73 * (Common.difficulty_scale()^(1.1)) * (Common.overworldx()/40)^(1.8) * (Public.crew_scale())^(55/100)-- There is no _explicit_ T dependence, but it depends almost the same way on the crew_scale as T does.
2.73 * (Common.difficulty_scale()^(1.1)) * (Common.overworldx()/40)^(1.8) * (Public.crew_scale())^(52/100)-- There is no _explicit_ T dependence, but it depends almost the same way on the crew_scale as T does.
) / Math.sloped(Common.difficulty_scale(), 1/5) --Final factor of difficulty is to offset a change made to scripted_biters_pollution_cost_multiplier
end
@ -330,18 +372,26 @@ function Public.resource_quest_multiplier()
return (1.0 + 0.075 * (Common.overworldx()/40)^(8/10)) * Math.sloped(Common.difficulty_scale(), 1/5) * (Public.crew_scale())^(1/10)
end
function Public.apply_crew_buffs_per_x(force)
force.laboratory_productivity_bonus = Math.max(0, 7/100 * (Common.overworldx()/40) - (10*(Common.difficulty_scale()) - 5)) --difficulty causes lab productivity boosts to start later
function Public.quest_structure_entry_price_scale()
return 0.85 * (1 + 0.033 * (Common.overworldx()/40 - 1)) * ((1 + Public.crew_scale())^(1/3)) * Math.sloped(Common.difficulty_scale(), 1/2) --whilst the scenario philosophy says that resource scales tend to be independent of crew size, we account slightly for the fact that more players tend to handcraft more
end
function Public.class_cost()
return 10000
function Public.apply_crew_buffs_per_league(force, leagues_travelled)
force.laboratory_productivity_bonus = force.laboratory_productivity_bonus + Math.max(0, 6/100 * leagues_travelled/40)
end
function Public.class_cost(at_dock)
if at_dock then
return 10000
else
return 6000
end
-- return Math.ceil(10000 / (Public.crew_scale()*10/4)^(1/6))
end
Public.covered_first_appears_at = 40
Public.quest_structures_first_appear_at = 40
Public.coin_sell_amount = 500
@ -367,7 +417,7 @@ function Public.sandworm_evo_increase_per_spawn()
end
function Public.kraken_kill_reward_items()
return {{name = 'sulfuric-acid-barrel', count = 5}, {name = 'coin', count = 1000}}
return {{name = 'sulfuric-acid-barrel', count = 5}, {name = 'coin', count = 800}}
end
function Public.kraken_kill_reward_fuel()
return 200
@ -494,9 +544,9 @@ function Public.player_gun_speed_modifiers()
end
Public.starting_items_player = {['pistol'] = 1, ['firearm-magazine'] = 12, ['raw-fish'] = 1, ['iron-plate'] = 12, ['medium-electric-pole'] = 4}
Public.starting_items_player = {['pistol'] = 1, ['firearm-magazine'] = 20, ['raw-fish'] = 4, ['medium-electric-pole'] = 20, ['iron-plate'] = 50, ['copper-plate'] = 20, ['iron-gear-wheel'] = 6, ['copper-cable'] = 20, ['burner-inserter'] = 2, ['gun-turret'] = 1}
Public.starting_items_player_late = {['pistol'] = 1, ['firearm-magazine'] = 5}
Public.starting_items_player_late = {['pistol'] = 1, ['firearm-magazine'] = 10, ['raw-fish'] = 4, ['small-electric-pole'] = 20, ['iron-plate'] = 50, ['copper-plate'] = 20, ['iron-gear-wheel'] = 6, ['copper-cable'] = 20, ['burner-inserter'] = 2, ['gun-turret'] = 1}
function Public.starting_items_crew_upstairs()
return {
@ -505,7 +555,7 @@ function Public.starting_items_crew_upstairs()
{['grenade'] = 3},
{['shotgun'] = 2, ['shotgun-shell'] = 36},
-- {['raw-fish'] = 5},
{['coin'] = 2000},
{['coin'] = 1000},
}
end
@ -517,7 +567,7 @@ function Public.starting_items_crew_downstairs()
{['inserter'] = Math.random(120,140)},
{['storage-tank'] = 2},
{['medium-electric-pole'] = Math.random(15,21)},
{['coin'] = 2000},
{['coin'] = 1000},
{['solar-panel'] = 3},
}
end
@ -525,116 +575,15 @@ end
function Public.covered_entry_price_scale()
return 0.85 * (1 + 0.033 * (Common.overworldx()/40 - 1)) * ((1 + Public.crew_scale())^(1/3)) * Math.sloped(Common.difficulty_scale(), 1/2) --whilst the scenario philosophy says that resource scales tend to be independent of crew size, we account slightly for the fact that more players tend to handcraft more
end
Public.covered1_entry_price_data_raw = { --watch out that the raw_materials chest can only hold e.g. 4.8 iron-plates
-- choose things that are easy to make at outposts
-- if the prices are too high, players will accidentally throw too much in when they can't do it
{1, 0, 1, false, {
price = {name = 'iron-stick', count = 1500},
raw_materials = {{name = 'iron-plate', count = 750}}}, {}},
{0.85, 0, 1, false, {
price = {name = 'copper-cable', count = 1500},
raw_materials = {{name = 'copper-plate', count = 750}}}, {}},
{1, 0, 0.3, false, {
price = {name = 'small-electric-pole', count = 450},
raw_materials = {{name = 'copper-plate', count = 900}}}, {}},
{1, 0.1, 1, false, {
price = {name = 'assembling-machine-1', count = 80},
raw_materials = {{name = 'iron-plate', count = 1760}, {name = 'copper-plate', count = 360}}}, {}},
{0.25, 0, 0.15, false, {
price = {name = 'burner-mining-drill', count = 150},
raw_materials = {{name = 'iron-plate', count = 1350}}}, {}},
{0.75, 0, 0.6, false, {
price = {name = 'burner-inserter', count = 300},
raw_materials = {{name = 'iron-plate', count = 900}}}, {}},
{1, 0.05, 0.7, false, {
price = {name = 'small-lamp', count = 300},
raw_materials = {{name = 'iron-plate', count = 600}, {name = 'copper-plate', count = 900}}}, {}},
{1, 0, 1, false, {
price = {name = 'firearm-magazine', count = 700},
raw_materials = {{name = 'iron-plate', count = 2800}}}, {}},
{0.6, 0, 1, false, {
price = {name = 'constant-combinator', count = 276},
raw_materials = {{name = 'iron-plate', count = 552}, {name = 'copper-plate', count = 1518}}}, {}},
{1, 0.05, 1, false, {
price = {name = 'stone-furnace', count = 250},
raw_materials = {}}, {}},
{1, 0.4, 1.6, true, {
price = {name = 'advanced-circuit', count = 180},
raw_materials = {{name = 'iron-plate', count = 360}, {name = 'copper-plate', count = 900}, {name = 'plastic-bar', count = 360}}}, {}},
{0.5, -0.5, 0.5, true, {
price = {name = 'wooden-chest', count = 400},
raw_materials = {}}, {}},
{0.5, 0, 1, true, {
price = {name = 'iron-chest', count = 250},
raw_materials = {{name = 'iron-plate', count = 2000}}}, {}},
{0.5, 0.25, 1.75, true, {
price = {name = 'steel-chest', count = 125},
raw_materials = {{name = 'steel-plate', count = 1000}}}, {}},
}
function Public.covered1_entry_price_data()
local ret = {}
local data = Public.covered1_entry_price_data_raw
for i = 1, #data do
local data_item = data[i]
ret[#ret + 1] = {
weight = data_item[1],
game_completion_progress_min = data_item[2],
game_completion_progress_max = data_item[3],
scaling = data_item[4],
item = data_item[5],
map_subtypes = data_item[6],
}
end
return ret
end
function Public.covered1_entry_price()
-- local rng = Math.random()
-- local memory = Memory.get_crew_memory()
-- local overworldx = memory.overworldx or 0
local game_completion_progress = Math.max(Math.min(Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress(), 1), 0)
local data = Public.covered1_entry_price_data()
local types, weights = {}, {}
for i = 1, #data, 1 do
table.insert(types, data[i].item)
local destination = Common.current_destination()
if not (data[i].map_subtypes and #data[i].map_subtypes > 0 and destination and destination.subtype and data[i].map_subtypes and (not Utils.contains(data[i].map_subtypes, destination.subtype))) then
if data[i].scaling then -- scale down weights away from the midpoint 'peak' (without changing the mean)
local midpoint = (data[i].game_completion_progress_max + data[i].game_completion_progress_min) / 2
local difference = (data[i].game_completion_progress_max - data[i].game_completion_progress_min)
table.insert(weights, data[i].weight * Math.max(0, 1 - (Math.abs(game_completion_progress - midpoint) / (difference / 2))))
else -- no scaling
if data[i].game_completion_progress_min <= game_completion_progress and data[i].game_completion_progress_max >= game_completion_progress then
table.insert(weights, data[i].weight)
else
table.insert(weights, 0)
end
end
end
end
local res = Utils.deepcopy(Math.raffle(types, weights))
res.price.count = Math.ceil(res.price.count * Public.covered_entry_price_scale())
for i, _ in pairs(res.raw_materials) do
res.raw_materials[i].count = Math.ceil(res.raw_materials[i].count * Public.covered_entry_price_scale() * (0.9 + 0.2 * Math.random()))
end
return res
end
return Public

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
@ -38,18 +40,18 @@ Public.List = {
}
Public.crowsnest_display_form = {
[enum.EXTRA_HOLD] = 'Extra Hold',
[enum.MORE_POWER] = 'Power',
[enum.UNLOCK_MERCHANTS] = 'Unlock Merchants',
[enum.ROCKETS_FOR_SALE] = 'Unlock Rockets',
[enum.EXTRA_HOLD] = {'pirates.upgrade_hold_crowsnest_form'},
[enum.MORE_POWER] = {'pirates.upgrade_power_crowsnest_form'},
[enum.UNLOCK_MERCHANTS] = {'pirates.upgrade_merchants_crowsnest_form'},
[enum.ROCKETS_FOR_SALE] = {'pirates.upgrade_rockets_crowsnest_form'},
}
-- WARNING: The dock market pulls from these values, but the Crowsnest caption pulls data from main_shop_data_1. So don't change one without the other
Public.market_offer_form = {
[enum.MORE_POWER] = {price = {{'coin', 7000}, {'coal', 500}}, offer = {type='nothing', effect_description='Upgrade the ship\'s passive power generators.'}},
[enum.EXTRA_HOLD] = {price = {{'coin', 7000}, {'coal', 500}}, offer = {type='nothing', effect_description='Purchase an extra hold.'}},
[enum.UNLOCK_MERCHANTS] = {price = {{'coin', 14000}, {'coal', 1000}}, offer = {type='nothing', effect_description='Unlock merchant ships on future islands.'}},
[enum.ROCKETS_FOR_SALE] = {price = {{'coin', 21000}, {'coal', 1000}}, offer = {type='nothing', effect_description='Unlock the sale of rockets at covered markets.'}},
[enum.MORE_POWER] = {price = {{'coin', 7000}, {'coal', 500}}, offer = {type='nothing', effect_description={'pirates.market_description_upgrade_power'}}},
[enum.EXTRA_HOLD] = {price = {{'coin', 7000}, {'coal', 500}}, offer = {type='nothing', effect_description={'pirates.market_description_upgrade_hold'}}},
[enum.UNLOCK_MERCHANTS] = {price = {{'coin', 14000}, {'coal', 1000}}, offer = {type='nothing', effect_description={'pirates.market_description_upgrade_merchants'}}},
[enum.ROCKETS_FOR_SALE] = {price = {{'coin', 21000}, {'coal', 1000}}, offer = {type='nothing', effect_description={'pirates.market_description_upgrade_rockets'}}},
}
function Public.execute_upgade(upgrade_type, player)
@ -59,23 +61,23 @@ function Public.execute_upgade(upgrade_type, player)
if upgrade_type == enum.EXTRA_HOLD then
if player then
Common.notify_force(player.force,string.format('[font=heading-1]%s upgraded the ship\'s hold.[/font]', player.name))
Common.notify_force(player.force,{'pirates.upgrade_hold',player.name})
end
Hold.add_another_hold_surface()
elseif upgrade_type == enum.MORE_POWER then
if player then
Common.notify_force(player.force, string.format('[font=heading-1]%s upgraded the ship\'s power.[/font]', player.name))
Common.notify_force(player.force, {'pirates.upgrade_power',player.name})
end
boat.EEI_stage = boat.EEI_stage + 1
Boats.update_EEIs(boat)
elseif upgrade_type == enum.UNLOCK_MERCHANTS then
if player then
Common.notify_force(player.force,string.format('[font=heading-1]%s unlocked merchant ships.[/font]', player.name))
Common.notify_force(player.force,{'pirates.upgrade_merchants',player.name})
end
memory.merchant_ships_unlocked = true
elseif upgrade_type == enum.ROCKETS_FOR_SALE then
if player then
Common.notify_force(player.force,string.format('[font=heading-1]%s unlocked the sale of rockets at covered-up markets.[/font]', player.name))
Common.notify_force(player.force,{'pirates.upgrade_rockets',player.name})
end
memory.rockets_for_sale = true
end

View File

@ -1,3 +1,5 @@
-- 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 mass requires is a code templating choice...
@ -24,7 +26,7 @@ local Islands = require 'maps.pirates.surfaces.islands.islands'
local Progression = require 'maps.pirates.progression'
local Crowsnest = require 'maps.pirates.surfaces.crowsnest'
local Hold = require 'maps.pirates.surfaces.hold'
local Interface = require 'maps.pirates.interface'
local PiratesApiEvents = require 'maps.pirates.api_events'
local Upgrades = require 'maps.pirates.boat_upgrades'
local Effects = require 'maps.pirates.effects'
local Kraken = require 'maps.pirates.surfaces.sea.kraken'
@ -38,150 +40,12 @@ local Classes = require 'maps.pirates.roles.classes'
local GUIcolor = require 'maps.pirates.gui.color'
commands.add_command(
'ok',
'is used to accept captainhood.',
function(cmd)
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
local function cmd_set_memory(cmd)
local crew_id = tonumber(string.sub(game.players[cmd.player_index].force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
Roles.player_confirm_captainhood(player)
end)
-- Disabled for information-flow reasons:
-- commands.add_command(
-- 'classes',
-- 'Prints the available classes in the game.',
-- function(cmd)
-- local player = game.players[cmd.player_index]
-- if not Common.validate_player(player) then return end
-- player.print('[color=gray]' .. Roles.get_classes_print_string() .. '[/color]')
-- end)
commands.add_command(
'classinfo',
'{classname} returns the definition of the named class.',
function(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)
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, '/classinfo {classname} returns the definition of the named class.')
end
end)
commands.add_command(
'take',
'{classname} takes a spare class with the given name for yourself.',
function(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
for _, class in ipairs(Classes.Class_List) do
if Classes.display_form[class]:lower() == param:lower() then
Classes.assign_class(player.index, class, true)
return true
end
end
--fallthrough:
Common.notify_player_error(player, 'Command error: Class \'' .. param .. '\' not found.')
return false
else
Common.notify_player_expected(player, '/take {classname} takes a spare class with the given name for yourself.')
end
end)
commands.add_command(
'giveup',
'gives up your current class, making it available for others.',
function(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
Classes.try_renounce_class(player, true)
else
Common.notify_player_error(player, 'Command error: parameter not needed.')
end
end)
commands.add_command(
'ccolor',
'is an extension to the built-in /color command, with more colors.',
function(cmd)
local param = tostring(cmd.parameter)
local player_index = cmd.player_index
if player_index then
local player = game.players[player_index]
if player and player.valid then
if cmd.parameter then
if PlayerColors.colors[param] then
local rgb = PlayerColors.colors[param]
player.color = rgb
player.chat_color = rgb
local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. ' chose the color ' .. param .. '[/color] (via /ccolor).'
Common.notify_game(message)
else
Common.notify_player_error(player, 'Command error: Color \'' .. param .. '\' not found.')
end
else
local color = PlayerColors.bright_color_names[Math.random(#PlayerColors.bright_color_names)]
local rgb = PlayerColors.colors[color]
if not rgb then return end
player.color = rgb
player.chat_color = rgb
local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color randomized to ' .. color .. '[/color] (via /ccolor).' --'randomly became' was amusing, but let's not
Common.notify_game(message)
-- disabled due to lag:
-- GUIcolor.toggle_window(player)
end
end
end
end)
local go_2 = Token.register(
function(data)
Memory.set_working_id(1)
local memory = Memory.get_crew_memory()
memory.mapbeingloadeddestination_index = 1
memory.loadingticks = 0
local surface = game.surfaces[Common.current_destination().surface_name]
-- surface.request_to_generate_chunks({x = 0, y = 0}, 10)
-- surface.force_generate_chunk_requests()
Progression.go_from_starting_dock_to_first_destination()
end
)
local go_1 = Token.register(
function(data)
Memory.set_working_id(1)
local memory = Memory.get_crew_memory()
Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth/2)
Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth/2)
Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth/2)
memory.currentdestination_index = 1
script.raise_event(CustomEvents.enum['update_crew_progress_gui'], {})
Surfaces.create_surface(Common.current_destination())
Task.set_timeout_in_ticks(60, go_2, {})
end
)
end
local function check_admin(cmd)
@ -212,9 +76,6 @@ local function check_captain(cmd)
if player ~= nil then
p = player.print
if not Common.validate_player(player) then return end
local crew_id = tonumber(string.sub(game.players[cmd.player_index].force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN) then
p('[ERROR] Only captains are allowed to run this command!', Color.fail)
return false
@ -235,9 +96,6 @@ local function check_captain_or_admin(cmd)
if player ~= nil then
p = player.print
if not Common.validate_player(player) then return end
local crew_id = tonumber(string.sub(game.players[cmd.player_index].force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (player.admin or Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN) then
p('[ERROR] Only captains are allowed to run this command!', Color.fail)
return false
@ -287,11 +145,237 @@ function(cmd)
end
end)
commands.add_command(
'sail',
'is an admin command to set the ship sailing after an island, in case there\'s a problem with the captain doing so.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local memory = Memory.get_crew_memory()
Crew.summon_crew()
if memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL then
Progression.at_sea_begin_to_set_sail()
end
end
end)
commands.add_command(
'setcaptain',
'{player} is an admin command to set the crew\'s captain to {player}.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
if param and game.players[param] and game.players[param].index then
Roles.make_captain(game.players[param])
else
Common.notify_player_error(player, 'Command error: Invalid player name.')
end
end
end)
commands.add_command(
'summoncrew',
'is an admin command to summon the crew to the ship.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Crew.summon_crew()
end
end)
commands.add_command(
'ok',
'is used to accept captainhood.',
function(cmd)
cmd_set_memory(cmd)
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
local memory = Memory.get_crew_memory()
Roles.player_confirm_captainhood(player)
end)
-- Disabled for information-flow reasons:
-- commands.add_command(
-- 'classes',
-- 'Prints the available classes in the game.',
-- function(cmd)
-- local player = game.players[cmd.player_index]
-- if not Common.validate_player(player) then return end
-- player.print('[color=gray]' .. Roles.get_classes_print_string() .. '[/color]')
-- end)
commands.add_command(
'classinfo',
'{classname} returns the definition of the named class.',
function(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, false)
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, '/classinfo {classname} returns the definition of the named class.')
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.',
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
for _, class in pairs(Classes.enum) do
if Classes.eng_form[class]:lower() == param:lower() then
Classes.assign_class(player.index, class, true)
return true
end
end
--fallthrough:
Common.notify_player_error(player, 'Command error: Class ' .. param .. ' not found.')
return false
else
Common.notify_player_expected(player, '/take {classname} takes a spare class with the given name for yourself.')
end
end)
commands.add_command(
'giveup',
'gives up your current class, making it available for others.',
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
Classes.try_renounce_class(player, true)
else
Common.notify_player_error(player, 'Command error: parameter not needed.')
end
end)
commands.add_command(
'ccolor',
'is an extension to the built-in /color command, with more colors.',
function(cmd)
local param = tostring(cmd.parameter)
local player_index = cmd.player_index
if player_index then
local player = game.players[player_index]
if player and player.valid then
if cmd.parameter then
if PlayerColors.colors[param] then
local rgb = PlayerColors.colors[param]
player.color = rgb
player.chat_color = rgb
local message = {'', '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']',{'pirates.choose_chat_color', player.name, param}, '[/color] (via /ccolor).'}
-- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. ' chose the color ' .. param .. '[/color] (via /ccolor).'
Common.notify_game(message)
else
Common.notify_player_error(player, 'Command error: Color \'' .. param .. '\' not found.')
end
else
local color = PlayerColors.bright_color_names[Math.random(#PlayerColors.bright_color_names)]
local rgb = PlayerColors.colors[color]
if not rgb then return end
player.color = rgb
player.chat_color = rgb
local message = {'', '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']', {'pirates.randomize_chat_color', player.name, color}, '[/color] (via /ccolor).'} --'randomly became' was amusing, but let's not
-- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color randomized to ' .. color .. '[/color] (via /ccolor).' --'randomly became' was amusing, but let's not
Common.notify_game(message)
-- disabled due to lag:
-- GUIcolor.toggle_window(player)
end
end
end
end)
local go_2 = Token.register(
function(data)
Memory.set_working_id(1)
local memory = Memory.get_crew_memory()
memory.mapbeingloadeddestination_index = 1
memory.loadingticks = 0
local surface = game.surfaces[Common.current_destination().surface_name]
-- surface.request_to_generate_chunks({x = 0, y = 0}, 10)
-- surface.force_generate_chunk_requests()
Progression.go_from_starting_dock_to_first_destination()
end
)
local go_1 = Token.register(
function(data)
Memory.set_working_id(1)
local memory = Memory.get_crew_memory()
Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth/2)
Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth/2)
Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth/2)
memory.currentdestination_index = 1
script.raise_event(CustomEvents.enum['update_crew_progress_gui'], {})
Surfaces.create_surface(Common.current_destination())
Task.set_timeout_in_ticks(60, go_2, {})
end
)
commands.add_command(
'plank',
'is a captain command to remove a player by making them a spectator.',
function(cmd)
cmd_set_memory(cmd)
local player = game.players[cmd.player_index]
local param = tostring(cmd.parameter)
if check_captain_or_admin(cmd) then
@ -307,6 +391,8 @@ commands.add_command(
'officer',
'is a captain command to make a player into an officer, or remove them as one.',
function(cmd)
cmd_set_memory(cmd)
local player = game.players[cmd.player_index]
local param = tostring(cmd.parameter)
if check_captain_or_admin(cmd) then
@ -327,6 +413,8 @@ commands.add_command(
'undock',
'is a captain command to undock the ship.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_captain_or_admin(cmd) then
local player = game.players[cmd.player_index]
@ -343,73 +431,43 @@ commands.add_command(
'tax',
'is a captain command to take a quarter of all coins, plus other game-critical items from the crew, into your inventory.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_captain(cmd) then
local player = game.players[cmd.player_index]
local memory = Memory.get_crew_memory()
Roles.captain_tax(memory.playerindex_captain)
end
end --@TODO: else
end)
commands.add_command(
'dump_highscores',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
local crew_id = tonumber(string.sub(game.players[cmd.player_index].force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
Highscore.dump_highscores()
player.print('Highscores dumped.')
end
end)
commands.add_command(
'setcaptain',
'{player} is an admin command to set the crew\'s captain to {player}.',
function(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 param and game.players[param] and game.players[param].index then
Roles.make_captain(game.players[param])
else
Common.notify_player_error(player, 'Command error: Invalid player name.')
end
end
end)
commands.add_command(
'summoncrew',
'is an admin command to summon the crew to the ship.',
function(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Crew.summon_crew()
end
end)
commands.add_command(
'setclass',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 Common.validate_player(player) then return end
if not memory.classes_table then memory.classes_table = {} end
memory.classes_table[player.index] = tonumber(param)
memory.classes_table[player.index] = param
player.print('Set own class to ' .. param .. '.')
end
end)
@ -418,11 +476,11 @@ commands.add_command(
'setevo',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Common.set_evo(tonumber(param))
end
end)
@ -431,11 +489,11 @@ commands.add_command(
'modi',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 surface = game.surfaces[Common.current_destination().surface_name]
local entities = surface.find_entities_filtered{position = player.position, radius = 500}
@ -455,11 +513,11 @@ commands.add_command(
'ret',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Progression.retreat_from_island(true)
end
end)
@ -468,11 +526,11 @@ commands.add_command(
'jump',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Overworld.try_overworld_move_v2({x = 40, y = 0})
end
end)
@ -481,11 +539,11 @@ commands.add_command(
'advu',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Overworld.try_overworld_move_v2{x = 0, y = -24}
end
end)
@ -494,11 +552,11 @@ commands.add_command(
'advd',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
Overworld.try_overworld_move_v2{x = 0, y = 24}
end
end)
@ -508,11 +566,11 @@ commands.add_command(
'overwrite_scores_specific',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
local crew_id = tonumber(string.sub(game.players[cmd.player_index].force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if Highscore.overwrite_scores_specific() then player.print('Highscores overwritten.') end
end
@ -566,16 +624,16 @@ if _DEBUG then
'chnk',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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()
for i = 0, 13 do
for j = 0, 13 do
Interface.event_on_chunk_generated({surface = player.surface, area = {left_top = {x = -7 * 32 + i * 32, y = -7 * 32 + j * 32}}})
PiratesApiEvents.event_on_chunk_generated({surface = player.surface, area = {left_top = {x = -7 * 32 + i * 32, y = -7 * 32 + j * 32}}})
end
end
game.print('chunks generated')
@ -586,11 +644,11 @@ if _DEBUG then
'spd',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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()
memory.boat.speed = 60
end
@ -600,11 +658,11 @@ if _DEBUG then
'stp',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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()
memory.boat.speed = 0
end
@ -695,15 +753,15 @@ if _DEBUG then
'score',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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()
game.print('faking a highscore...')
Highscore.write_score(memory.secs_id, 'fakers', 0, 40, CoreData.version_float, 1, 1)
Highscore.write_score(memory.secs_id, 'fakers', 0, 40, CoreData.version_string, 1, 1)
end
end)
@ -804,6 +862,28 @@ if _DEBUG then
end
end)
commands.add_command(
'1/4',
'is a dev command.',
function(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
game.speed = 0.5
end
end)
commands.add_command(
'1/2',
'is a dev command.',
function(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
game.speed = 0.5
end
end)
commands.add_command(
'1',
'is a dev command.',
@ -885,11 +965,11 @@ if _DEBUG then
'ef1',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 surface = game.surfaces[Common.current_destination().surface_name]
Effects.worm_movement_effect(surface, {x = -45, y = 0}, false, true)
@ -900,11 +980,11 @@ if _DEBUG then
'ef2',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 surface = game.surfaces[Common.current_destination().surface_name]
Effects.worm_movement_effect(surface, {x = -45, y = 0}, false, false)
@ -915,11 +995,11 @@ if _DEBUG then
'ef3',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 surface = game.surfaces[Common.current_destination().surface_name]
Effects.worm_movement_effect(surface, {x = -45, y = 0}, true, false)
@ -930,11 +1010,11 @@ if _DEBUG then
'ef4',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 surface = game.surfaces[Common.current_destination().surface_name]
Effects.worm_emerge_effect(surface, {x = -45, y = 0})
@ -945,11 +1025,11 @@ if _DEBUG then
'ef5',
'is a dev command.',
function(cmd)
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.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 surface = game.surfaces[Common.current_destination().surface_name]
Effects.biters_emerge(surface, {x = -30, y = 0})
@ -966,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

View File

@ -1,5 +1,8 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Math = require 'maps.pirates.math'
local Raffle = require 'maps.pirates.raffle'
local Server = require 'utils.server'
local Utils = require 'maps.pirates.utils_local'
local CoreData = require 'maps.pirates.coredata'
@ -15,9 +18,9 @@ local _inspect = require 'utils.inspect'.inspect
local Public = {}
-- Public.active_crews_cap = 1
Public.active_crews_cap = 2
Public.minimum_capacity_slider_value = 1
Public.minimum_run_capacity_to_enforce_space_for = 32
Public.activeCrewsCap = 2
Public.minimumCapacitySliderValue = 1
Public.minimum_run_capacity_to_enforce_space_for = 22
-- auto-disbanding when there are no players left in the crew:
Public.autodisband_ticks = nil
-- Public.autodisband_ticks = 30*60*60
@ -32,17 +35,21 @@ Public.boat_default_starting_distance_from_shore = 22
Public.mapedge_distance_from_boat_starting_position = 272 -- to accommodate horseshoe
Public.deepwater_distance_from_leftmost_shore = 32
Public.lobby_spawnpoint = {x = -72, y = -8}
Public.structure_ensure_chunk_radius = 2
Public.quartermaster_range = 17
Public.allow_barreling_off_ship = true
Public.fraction_of_map_loaded_atsea = 1
Public.coin_tax_percentage = 10
Public.fraction_of_map_loaded_at_sea = 1
Public.map_loading_ticks_atsea = 68 * 60
Public.map_loading_ticks_atsea_maze = 80 * 60
Public.map_loading_ticks_atsea_dock = 20 * 60
Public.map_loading_ticks_onisland = 2 * 60 * 60
Public.loading_interval = 5
Public.first_cost_to_leave_macrox = 7
Public.minimum_ore_placed_per_tile = 10
Public.maze_minimap_jam_league = 960
@ -52,7 +59,7 @@ Public.ban_from_rejoining_crew_ticks = 45 * 60 --to prevent observing map and re
Public.afk_time = 60 * 60 * 5
Public.afk_warning_time = 60 * 60 * 4.5
Public.logged_off_items_preserved_minutes = 5
Public.logout_unprotected_items = {'coin', 'uranium-235', 'rail-signal', 'uranium-238', 'fluid-wagon', 'coal', 'electric-engine-unit', 'flying-robot-frame', 'advanced-circuit', 'beacon', 'speed-module-3', 'speed-module-2', 'roboport', 'construction-robot'} --internal inventories of these will not be preserved
Public.logout_unprotected_items = {'uranium-235', 'uranium-238', 'fluid-wagon', 'coal', 'electric-engine-unit', 'flying-robot-frame', 'advanced-circuit', 'beacon', 'speed-module-3', 'speed-module-2', 'roboport', 'construction-robot'} --internal inventories of these will not be preserved
-- Public.mainshop_rate_limit_ticks = 11
@ -84,7 +91,7 @@ function Public.capacity() return Memory.get_crew_memory().capacity end
-- function Public.mode() return Memory.get_crew_memory().mode end
function Public.overworldx() return Memory.get_crew_memory().overworldx end
function Public.game_completion_progress() return Public.overworldx()/CoreData.victory_x end
function Public.game_completion_progress_capped() return Math.min(Public.overworldx()/CoreData.victory_x, 1) end
function Public.game_completion_progress_capped() return Math.clamp(0, 1, Public.overworldx()/CoreData.victory_x) end
function Public.capacity_scale()
local capacity = Public.capacity()
if not capacity then --e.g. for EE wattage on boats not owned by a crew
@ -121,49 +128,51 @@ end
function Public.notify_game(message, color_override)
color_override = color_override or CoreData.colors.notify_game
game.print('>> ' .. message, color_override)
game.print({"", '>> ', message}, color_override)
end
function Public.notify_lobby(message, color_override)
color_override = color_override or CoreData.colors.notify_lobby
game.forces['player'].print('>> ' .. message, color_override)
game.forces['player'].print({"", '>> ', message}, color_override)
end
function Public.notify_force(force, message, color_override)
color_override = color_override or CoreData.colors.notify_force
force.print('>> ' .. message, color_override)
force.print({"", '>> ', message}, color_override)
end
function Public.notify_force_light(force, message, color_override)
color_override = color_override or CoreData.colors.notify_force_light
force.print('>> ' .. message, color_override)
force.print({"", '>> ', message}, color_override)
end
function Public.notify_force_error(force, message, color_override)
color_override = color_override or CoreData.colors.notify_error
force.print('>> ' .. message, color_override)
force.print({"", '>> ', message}, color_override)
force.play_sound{path = "utility/cannot_build"}
end
function Public.notify_player_error(player, message, color_override)
color_override = color_override or CoreData.colors.notify_error
player.print('## [Whisper] ' .. message, color_override)
player.print({"", '## ', {'pirates.notify_whisper'}, ' ', message}, color_override)
player.play_sound{path = "utility/cannot_build"}
end
function Public.notify_player_expected(player, message, color_override)
color_override = color_override or CoreData.colors.notify_player_expected
player.print('>> [Whisper] ' .. message, color_override)
player.print({"", '## ', {'pirates.notify_whisper'}, ' ', message}, color_override)
end
function Public.notify_player_announce(player, message, color_override)
color_override = color_override or CoreData.colors.notify_player_announce
player.print('>> [Whisper] ' .. message, color_override)
player.print({"", '## ', {'pirates.notify_whisper'}, ' ', message}, color_override)
end
function Public.parrot_speak(force, message)
force.print('Parrot: ' .. message, CoreData.colors.parrot)
force.print({"", {'pirates.notify_parrot'}, ' ', message}, CoreData.colors.parrot)
local memory = Memory.get_crew_memory()
Server.to_discord_embed_raw('[' .. memory.name .. '] Parrot: ' .. message)
Server.to_discord_embed_raw({"", '[' .. memory.name .. '] ', {'pirates.notify_parrot'}, ' ', message}, true)
end
@ -216,6 +225,9 @@ end
-- {20, 0, 1, false, 'flying-robot-frame', 20, 35},
-- }
--@TODO: Replace this old function with the newer code in raffle.lua
function Public.raffle_from_processed_loot_data(processed_loot_data, how_many, game_completion_progress)
local ret = {}
@ -242,7 +254,7 @@ function Public.raffle_from_processed_loot_data(processed_loot_data, how_many, g
end
for _ = 1, how_many do
local loot = Math.raffle(loot_types, loot_weights)
local loot = Raffle.raffle(loot_types, loot_weights)
if loot then
local low = Math.max(1, Math.ceil(loot.min_count))
local high = Math.max(1, Math.ceil(loot.max_count))
@ -264,7 +276,7 @@ end
function Public.give(player, stacks, spill_position, spill_surface, flying_text_position)
function Public.give(player, stacks, spill_position, short_form, spill_surface, flying_text_position)
-- stack elements of form {name = '', count = '', color = {r = , g = , b = }}
-- to just spill on the ground, pass player and nill and give a position and surface directly
spill_position = spill_position or player.position
@ -325,22 +337,26 @@ function Public.give(player, stacks, spill_position, spill_surface, flying_text_
end
end
if itemcount_remember > 0 then
if #stacks2 == 1 and itemname == 'coin' and itemcount_remember == 1 then --for a single coin, drop the '+'
text1 = text1 .. '[item=' .. itemname .. ']'
if itemcount_remember >= 0 then
if short_form then
text1 = text1 .. '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. ']' .. '+' .. itemcount_remember .. '[/color]'
else
text1 = text1 .. '[color=1,1,1]'
text1 = text1 .. '+'
text1 = text1 .. itemcount_remember .. '[/color] [item=' .. itemname .. ']'
end
else
text1 = text1 .. '[color=1,1,1]'
text1 = text1 .. '-'
text1 = text1 .. -itemcount_remember .. '[/color] [item=' .. itemname .. ']'
if short_form then
text1 = text1 .. '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. ']' .. '-' .. -itemcount_remember .. '[/color]'
else
text1 = text1 .. '[color=1,1,1]'
text1 = text1 .. '-'
text1 = text1 .. -itemcount_remember .. '[/color] [item=' .. itemname .. ']'
end
end
if player and not (#stacks2 == 1 and itemname == 'coin') then
if player and (not short_form) then
-- count total of that item they have:
local new_total_count = 0
@ -398,6 +414,7 @@ end
-- -- return Math.floor(surplus_evo*3*1000)/1000
-- end
function Public.set_biter_surplus_evo_modifiers()
local memory = Memory.get_crew_memory()
local enemy_force = memory.enemy_force
@ -780,8 +797,7 @@ function Public.spawner_count(surface)
local memory = Memory.get_crew_memory()
local spawners = surface.find_entities_filtered({type = 'unit-spawner', force = memory.enemy_force_name})
local spawnerscount = #spawners or 0
return spawnerscount
return #spawners or 0
end
@ -981,16 +997,42 @@ function Public.add_tiles_from_blueprint(tilesTable, bp_string, tile_name, offse
end
function Public.tile_positions_from_blueprint(bp_string, offset)
-- May '22 change: There seems to be a base game bug(?) which causes the tiles to be offset. We now correct for that (with ` - (max_x - min_x)/2` and ` - (max_y - min_y)/2`).
local bp_entity = game.surfaces['nauvis'].create_entity{name = 'item-on-ground', position = {x = 158.5, y = 158.5}, stack = 'blueprint'}
bp_entity.stack.import_stack(bp_string)
local bp_tiles = bp_entity.stack.get_blueprint_tiles()
local min_x
local min_y
local max_x
local max_y
local positions = {}
if bp_tiles then
for _, tile in pairs(bp_tiles) do
positions[#positions + 1] = {x = tile.position.x + offset.x, y = tile.position.y + offset.y}
positions[#positions + 1] = {x = tile.position.x, y = tile.position.y}
if not min_x or tile.position.x < min_x then
min_x = tile.position.x
end
if not min_y or tile.position.y < min_y then
min_y = tile.position.y
end
if not max_x or tile.position.x > max_x then
max_x = tile.position.x
end
if not max_y or tile.position.y > max_y then
max_y = tile.position.y
end
end
end
if min_x and min_y and max_x and max_y then
for _, pos in pairs(positions) do
pos.x = pos.x - (max_x - min_x)/2 + offset.x
pos.y = pos.y - (max_y - min_y)/2 + offset.y
end
end
@ -1000,6 +1042,7 @@ function Public.tile_positions_from_blueprint(bp_string, offset)
end
function Public.tile_positions_from_blueprint_arrayform(bp_string, offset)
-- does not include the above May '22 fix yet, so may give different results
local bp_entity = game.surfaces['nauvis'].create_entity{name = 'item-on-ground', position = {x = 158.5, y = 158.5}, stack = 'blueprint'}
bp_entity.stack.import_stack(bp_string)
@ -1255,7 +1298,7 @@ function Public.send_important_items_from_player_to_crew(player, all_items)
end
function Public.give_items_to_crew(items, prefer_alternate_chest)
function Public.give_items_to_crew(items)
local memory = Memory.get_crew_memory()
local boat = memory.boat
@ -1265,7 +1308,8 @@ function Public.give_items_to_crew(items, prefer_alternate_chest)
local surface = game.surfaces[surface_name]
if not (surface and surface.valid) then return end
local chest, chest2
if prefer_alternate_chest then
if items.name and items.name == 'coin' then
chest = boat.backup_output_chest
if not (chest and chest.valid) then return end
chest2 = boat.output_chest
@ -1321,6 +1365,51 @@ function Public.give_items_to_crew(items, prefer_alternate_chest)
end
function Public.version_to_array(v)
local vArray = {}
if type(v) == 'number' then --this is a legacy form
local vs = tostring(v)
for i = 1, string.len(vs) do
local char = vs:sub(i, i)
if i ~= 2 then
vArray[#vArray+1] = char
end
end
else
for i = 1, string.len(v) do
local char = v:sub(i, i)
if char ~= '.' then
vArray[#vArray+1] = char
end
end
end
return vArray
end
function Public.version_greater_than(v1, v2)
local v1Array = Public.version_to_array(v1)
local v2Array = Public.version_to_array(v2)
for i = 1, math.max(#v1Array, #v2Array) do
local v1i = tonumber(v1Array[i])
local v2i = tonumber(v2Array[i])
if v1i ~= nil and v2i ~= nil then
if v1i < v2i then
return false
elseif v1i > v2i then
return true
end
elseif v1i == nil then
return false
else
return true
end
end
end
function Public.init_game_settings(technology_price_multiplier)

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Math = require 'maps.pirates.math'
local _inspect = require 'utils.inspect'.inspect
@ -5,8 +7,7 @@ local _inspect = require 'utils.inspect'.inspect
local Public = {}
Public.scenario_id_name = 'pirates'
Public.version_string = '1.2.2' --will now try to stick to major.minor.patch versioning, to match factorio mod portal
Public.version_float = 1.22
Public.version_string = '1.2.14' --major.minor.patch versioning, to match factorio mod portal
Public.blueprint_library_allowed = true
Public.blueprint_importing_allowed = true
@ -43,6 +44,7 @@ Public.colors = {
renderingtext_green = {r=88, g=219, b=88},
renderingtext_yellow = {r=79, g=136, b=209},
quartermaster_rendering = {r=237, g=157, b=45, a=0.15},
toughness_rendering = {r=40, g=40, b=40, a=0.5},
}
Public.static_boat_floor = 'brown-refined-concrete'
@ -107,25 +109,41 @@ Public.capacity_options = {
{value = 999, icon = 'virtual-signal/signal-white', text = 'Inf.', text2 = '', text3 = 'Inf'},
-- {value = 64, icon = 'item/storage-tank', text = '64'},
}
Public.difficulty_options = {
-- The difficulty values we currently offer
--For the value of Easy difficulty, we are pulled in two directions: We wish to make the game comfy to play for those who haven't played it, but we also wish to represent the game mechanics faithfully so that Normal is not a crazy distance away.
{value = 0.6, icon = 'item/firearm-magazine', text = 'Easy', associated_color = {r = 50, g = 255, b = 50}},
{value = 1.0, icon = 'item/piercing-rounds-magazine', text = 'Normal', associated_color = {r = 255, g = 255, b = 50}},
{value = 1.4, icon = 'item/uranium-rounds-magazine', text = 'Hard', associated_color = {r = 255, g = 50, b = 50}},
{value = 2.4, icon = 'item/atomic-bomb', text = 'Nightmare', associated_color = {r = 120, g = 35, b = 35}},
{value = 0.6, icon = 'item/firearm-magazine', text = {'pirates.difficulty_easy'}, associated_color = {r = 50, g = 255, b = 50}},
{value = 1.0, icon = 'item/piercing-rounds-magazine', text = {'pirates.difficulty_normal'}, associated_color = {r = 255, g = 255, b = 50}},
{value = 1.4, icon = 'item/uranium-rounds-magazine', text = {'pirates.difficutly_hard'}, associated_color = {r = 255, g = 50, b = 50}},
{value = 2.1, icon = 'item/atomic-bomb', text = {'pirates.difficulty_nightmare'}, associated_color = {r = 170, g = 60, b = 60}},
}
function Public.get_difficulty_name_from_value(difficulty_value)
-- Functions will reference this when given a difficulty value and want to present a difficulty name to the player; just make it consistent with the above
if difficulty_value <= 0.7 then
return 'Easy'
elseif difficulty_value < 1.3 then
return 'Normal'
elseif difficulty_value <= 2 then
return 'Hard'
function Public.get_difficulty_option_from_value(difficulty_value)
-- given a difficulty value, key in to the closesy entry in the above table. (organising things this way allows us to make changes to the 'value' keys in the above table without disrupting e.g. past highscores data)
if difficulty_value <= 0.8 then
return 1
elseif difficulty_value < 1.2 then
return 2
elseif difficulty_value <= 1.75 then
return 3
else
return 'Nightmare'
return 4
end
end
function Public.get_difficulty_option_informal_name_from_value(difficulty_value)
-- given a difficulty value, provide a simple named description of the difficulty. for internal use
if difficulty_value <= 0.8 then
return 'easy'
elseif difficulty_value < 1.2 then
return 'normal'
elseif difficulty_value <= 1.75 then
return 'hard'
else
return 'nightmare'
end
end
@ -135,11 +153,11 @@ end
-- }
Public.daynightcycle_types = {
{displayname = 'Static', 0},
{displayname = 'Slow Cyclic', ticksperday = 100000},
{displayname = 'Cyclic', ticksperday = 80000},
{displayname = 'Fast Cyclic', ticksperday = 60000},
{displayname = 'Rapid Cyclic', ticksperday = 40000},
{displayname = {'pirates.daynightcycle_static'}, 0},
{displayname = {'pirates.daynightcycle_slowcyclic'}, ticksperday = 100000},
{displayname = {'pirates.daynightcycle_cyclic'}, ticksperday = 80000},
{displayname = {'pirates.daynightcycle_fastcyclic'}, ticksperday = 60000},
{displayname = {'pirates.daynightcycle_rapidcyclic'}, ticksperday = 40000},
}
Public.ore_types = {
@ -190,8 +208,11 @@ Public.biterPollutionValues = {
-- ['small-spitter'] = 4
-- }
--@TODO: Add a function to compare/print two version numbers
Public.max_extra_seconds_at_sea = 8 * 60
Public.loco_bp_1 = [[0eNqV0ttqwzAMBuB30bVTVufsVxljpKloBYkcbLdrCH73Oi6UMrxDLm3zf7KEFjgMF5wMsQO1APWaLaj3BSyduBvWOzdPCArI4QgCuBvX06B7PWpHVwQvgPiIN1B7L/4Mmo6Gl4j0HwKQHTnCR+F4mD/5Mh7QBDNVUsCkbYhoXusEJmsFzKCqAGtDgegej2/rj76J8il+aX1EzvozWpcwm10ZVbkrfcLJ/+u0vzvF07EuTOd0dlkc0k9NJpFyI1KnkGrrZJp0R/XWyUQnLEJcFfWykgKuaGxMyGZf1K2sC5nnTVl5fwdTR+VL]]
function Public.Dock_iconized_map()

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Balance = require 'maps.pirates.balance'
local _inspect = require 'utils.inspect'.inspect
@ -32,18 +34,21 @@ Public.enum = enum
function Public.difficulty_vote(player_index, difficulty_id)
local memory = Memory.get_crew_memory()
if not (memory.difficulty_votes) then memory.difficulty_votes = {} end
local player = game.players[player_index]
if not (player and player.valid) then return end
if memory.difficulty_votes[player_index] and memory.difficulty_votes[player_index] == difficulty_id then
return nil
else
log(_inspect(CoreData.difficulty_options))
local option = CoreData.difficulty_options[difficulty_id]
if not option then return end
local color = option.associated_color
Common.notify_force(memory.force, player.name .. ' voted [color=' .. color.r .. ',' .. color.g .. ',' .. color.b .. ']for difficulty ' .. option.text .. '[/color]')
Common.notify_force(memory.force, {'pirates.notify_difficulty_vote',player.name, color.r, color.g, color.b, option.text})
memory.difficulty_votes[player_index] = difficulty_id
@ -75,11 +80,13 @@ function Public.update_difficulty()
if modal_id ~= memory.difficulty_option then
local color = CoreData.difficulty_options[modal_id].associated_color
local message1 = 'Difficulty [color=' .. color.r .. ',' .. color.g .. ',' .. color.b .. ']changed to ' .. CoreData.difficulty_options[modal_id].text .. '[/color].'
local message2 = 'Difficulty changed to ' .. CoreData.difficulty_options[modal_id].text .. '.'
local message1 = {'pirates.notify_difficulty_change', color.r, color.g, color.b, CoreData.difficulty_options[modal_id].text}
Common.notify_force(memory.force, message1)
Server.to_discord_embed_raw(CoreData.comfy_emojis.kewl .. '[' .. memory.name .. '] ' .. message2)
-- local message2 = 'Difficulty changed to ' .. CoreData.difficulty_options[modal_id].text .. '.'
Server.to_discord_embed_raw({'', CoreData.comfy_emojis.kewl .. '[' .. memory.name .. '] ', message1}, true)
memory.difficulty_option = modal_id
memory.difficulty = CoreData.difficulty_options[modal_id].value
@ -113,7 +120,7 @@ function Public.get_crewmembers_printable_string()
return crewmembers_string
end
function Public.try_lose(reason)
function Public.try_lose(loss_reason)
local memory = Memory.get_crew_memory()
if (not memory.game_lost) then
@ -123,9 +130,13 @@ function Public.try_lose(reason)
local playtimetext = Utils.time_longform((memory.age or 0)/60)
Server.to_discord_embed_raw(CoreData.comfy_emojis.trashbin .. '[' .. memory.name .. '] Game over — ' .. reason ..'. Playtime: ' .. playtimetext .. ' since 1st island. Crewmembers: ' .. Public.get_crewmembers_printable_string())
local message = {'',loss_reason,' ',{'pirates.loss_rest_of_message_long', playtimetext, Public.get_crewmembers_printable_string()}}
Common.notify_game('[' .. memory.name .. '] Game over — ' .. reason ..'. Playtime: [font=default-large-semibold]' .. playtimetext .. '[/font] since 1st island.', CoreData.colors.notify_gameover)
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.trashbin .. '[' .. memory.name .. '] ', message}, true)
local message2 = {'',loss_reason,' ',{'pirates.loss_rest_of_message_short', '[font=default-large-semibold]' .. playtimetext .. '[/font]'}}
Common.notify_game({'', '[' .. memory.name .. '] ',message2}, CoreData.colors.notify_gameover)
local force = memory.force
if not (force and force.valid) then return end
@ -146,9 +157,9 @@ function Public.try_win()
memory.game_won = true
-- memory.crew_disband_tick = game.tick + 1200
Server.to_discord_embed_raw(CoreData.comfy_emojis.goldenobese .. '[' .. memory.name .. '] Victory, on v' .. CoreData.version_string .. ', ' .. CoreData.difficulty_options[memory.difficulty_option].text .. ', capacity ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '. Playtime: ' .. speedrun_time_str .. ' since 1st island. Crewmembers: ' .. Public.get_crewmembers_printable_string())
Server.to_discord_embed_raw({'', CoreData.comfy_emojis.goldenobese .. '[' .. memory.name .. '] Victory, on v' .. CoreData.version_string .. ', ', CoreData.difficulty_options[memory.difficulty_option].text, ', capacity ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '. Playtime: ' .. speedrun_time_str .. ' since 1st island. Crewmembers: ' .. Public.get_crewmembers_printable_string()}, true)
Common.notify_game('[' .. memory.name .. '] Victory, on v' .. CoreData.version_string .. ', ' .. CoreData.difficulty_options[memory.difficulty_option].text .. ', capacity ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '. Playtime: [font=default-large-semibold]' .. speedrun_time_str .. '[/font] since 1st island. Crewmembers: ' .. Public.get_crewmembers_printable_string(), CoreData.colors.notify_victory)
Common.notify_game({'','[' .. memory.name .. '] ',{'pirates.victory',CoreData.version_string, CoreData.difficulty_options[memory.difficulty_option].text, CoreData.capacity_options[memory.capacity_option].text3, speedrun_time_str, Public.get_crewmembers_printable_string()}}, CoreData.colors.notify_victory)
game.play_sound{path='utility/game_won', volume_modifier=0.9}
@ -226,9 +237,8 @@ function Public.join_spectators(player, crewid)
if char and char.valid then
local p = char.position
-- local surface_name = char.surface.name
local message = player.name .. ' left the crew'
if p then
Common.notify_force(force, message .. ' to become a spectator.')
Common.notify_force(force, {'pirates.crew_to_spectator', player.name})
-- Server.to_discord_embed_raw(CoreData.comfy_emojis.feel .. '[' .. memory.name .. '] ' .. message)
end
-- if p then
@ -241,8 +251,7 @@ function Public.join_spectators(player, crewid)
player.set_controller{type = defines.controllers.spectator}
else
local message = player.name .. ' left the crew'
Common.notify_force(force, message .. ' to become a spectator.')
Common.notify_force(force, {'pirates.crew_to_spectator', player.name})
-- Server.to_discord_embed_raw(CoreData.comfy_emojis.feel .. '[' .. memory.name .. '] ' .. message)
player.set_controller{type = defines.controllers.spectator}
end
@ -264,8 +273,8 @@ function Public.join_spectators(player, crewid)
player.force = force
player.associate_character(c)
Common.notify_force(force, player.name .. ' joined as a spectator.')
Common.notify_lobby(player.name .. ' left the lobby to spectate ' .. memory.name .. '.')
Common.notify_force(force, {'pirates.lobby_to_spectator', player.name})
Common.notify_lobby({'pirates.lobby_to_spectator_2', player.name, memory.name})
end
memory.spectatorplayerindices[#memory.spectatorplayerindices + 1] = player.index
memory.tempbanned_from_joining_data[player.index] = game.tick
@ -288,7 +297,7 @@ function Public.leave_spectators(player, quiet)
if not Common.validate_player(player) then return end
if not quiet then
Common.notify_force(player.force, player.name .. ' stopped spectating and returned to the lobby.')
Common.notify_force(player.force, {'pirates.spectator_to_lobby', player.name})
end
local chars = player.get_associated_characters()
@ -359,17 +368,16 @@ function Public.join_crew(player, crewid, rejoin)
player.force = game.forces[string.format('crew-%03d', memory.id)]
player.teleport(surface.find_non_colliding_position('character', memory.spawnpoint, 32, 0.5) or memory.spawnpoint, surface)
Common.notify_lobby(player.name .. ' left the lobby to join ' .. memory.name .. '.')
Common.notify_lobby({'pirates.lobby_to_crew_2', player.name, memory.name})
end
local message = player.name .. ' joined the crew.'
Common.notify_force(player.force, message)
Common.notify_force(player.force, {'pirates.lobby_to_crew', player.name})
-- Server.to_discord_embed_raw(CoreData.comfy_emojis.yum1 .. '[' .. memory.name .. '] ' .. message)
memory.crewplayerindices[#memory.crewplayerindices + 1] = player.index
-- don't give them items if they've been in the crew recently:
if not (memory.tempbanned_from_joining_data and memory.tempbanned_from_joining_data[player.index] and game.tick < memory.tempbanned_from_joining_data[player.index] + 8 * Common.ban_from_rejoining_crew_ticks) and (not rejoin) then
if not (memory.tempbanned_from_joining_data and memory.tempbanned_from_joining_data[player.index]) and (not rejoin) then --just using tempbanned_from_joining_data as a quick proxy for whether the player has ever been in this run before
for item, amount in pairs(Balance.starting_items_player_late) do
player.insert({name = item, count = amount})
end
@ -381,16 +389,14 @@ function Public.join_crew(player, crewid, rejoin)
memory.crew_disband_tick = nil --to prevent disbanding the crew after saving the game (booting everyone) and loading it again (joining the crew as the only member)
end
local personal_str = 'You have joined the crew \'' .. memory.name
if memory.overworldx > 0 then
local color = CoreData.difficulty_options[memory.difficulty_option].associated_color
personal_str = personal_str .. '\' [Capacity ' .. CoreData.capacity_options[memory.capacity_option].text3 .. ', Difficulty [color=' .. color.r .. ',' .. color.g .. ',' .. color.b .. ']' .. CoreData.difficulty_options[memory.difficulty_option].text .. '[/color]].'
Common.notify_player_announce(player, {'pirates.personal_join_string_1', memory.name, CoreData.capacity_options[memory.capacity_option].text3, color.r, color.g, color.b, CoreData.difficulty_options[memory.difficulty_option].text})
else
personal_str = personal_str .. '\' [Capacity ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '].'
Common.notify_player_announce(player, {'pirates.personal_join_string_1', memory.name, CoreData.capacity_options[memory.capacity_option].text3})
end
Common.notify_player_announce(player, personal_str)
end
end
@ -405,10 +411,8 @@ function Public.leave_crew(player, to_lobby, quiet)
if char and char.valid then
-- local p = char.position
-- local surface_name = char.surface.name
local message
if not quiet then
message = player.name .. ' left the crew.'
Common.notify_force(player.force, message)
Common.notify_force(player.force, {'pirates.crew_leave', player.name})
-- else
-- message = player.name .. ' left.'
end
@ -483,20 +487,19 @@ function Public.plank(captain, player)
if Utils.contains(Common.crew_get_crew_members(), player) then
if (not (captain.index == player.index)) then
local message = "%s planked %s!"
Server.to_discord_embed_raw(CoreData.comfy_emojis.monkas .. string.format(message, captain.name, player.name))
Server.to_discord_embed_raw(CoreData.comfy_emojis.monkas .. string.format("%s planked %s!", captain.name, player.name))
Common.notify_force(player.force, string.format(message, captain.name, player.name))
Common.notify_force(player.force, {'pirates.plank', captain.name, player.name})
Public.join_spectators(player, memory.id)
memory.tempbanned_from_joining_data[player.index] = game.tick + 60 * 120
return true
else
Common.notify_player_error(captain, 'Command error: Can\'t plank yourself.')
Common.notify_player_error(player, {'pirates.plank_error_self'})
return false
end
else
Common.notify_player_error(captain, 'Command error: Player is not a crewmember.')
Common.notify_player_error(player, {'pirates.plank_error_invalid_player'})
return false
end
end
@ -519,9 +522,9 @@ function Public.disband_crew(donotprint)
if (not donotprint) then
local message = '[' .. memory.name .. '] Disbanded after ' .. Utils.time_longform((memory.real_age or 0)/60) .. '.'
local message = {'pirates.crew_disband', memory.name, Utils.time_longform((memory.real_age or 0)/60)}
Common.notify_game(message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.monkas .. message)
Server.to_discord_embed_raw({'', CoreData.comfy_emojis.monkas, message}, true)
-- if memory.game_won then
-- game.print({'chronosphere.message_game_won_restart'}, {r=0.98, g=0.66, b=0.22})
@ -613,7 +616,7 @@ function Public.player_abandon_proposal(player)
for k, proposal in pairs(global_memory.crewproposals) do
if proposal.endorserindices and proposal.endorserindices[1] and proposal.endorserindices[1] == player.index then
proposal.endorserindices[k] = nil
Common.notify_lobby('Proposal ' .. proposal.name .. ' retracted.')
Common.notify_lobby({'pirates.proposal_retracted', proposal.name})
-- Server.to_discord_embed(message)
global_memory.crewproposals[k] = nil
end
@ -628,7 +631,7 @@ function Public.player_abandon_endorsements(player)
if i == player.index then
proposal.endorserindices[k2] = nil
if #proposal.endorserindices == 0 then
Common.notify_lobby('Proposal ' .. proposal.name .. ' abandoned.')
Common.notify_lobby({'pirates.proposal_abandoned', proposal.name})
-- Server.to_discord_embed(message)
global_memory.crewproposals[k] = nil
end
@ -696,6 +699,8 @@ function Public.initialise_crew(accepted_proposal)
memory.tempbanned_from_joining_data = {}
memory.destinations = {}
memory.temporarily_logged_off_characters = {}
memory.class_renderings = {}
memory.class_auxiliary_data = {}
memory.hold_surface_count = 1
@ -745,17 +750,17 @@ function Public.initialise_crew(accepted_proposal)
local crew_force = game.forces[string.format('crew-%03d', new_id)]
crew_force.set_spawn_position(memory.spawnpoint, surface)
local message = '[' .. accepted_proposal.name .. '] Launched.'
local message = {'pirates.crew_launch', accepted_proposal.name}
Common.notify_game(message)
-- Server.to_discord_embed_raw(CoreData.comfy_emojis.pogkot .. message .. ' Difficulty: ' .. CoreData.difficulty_options[memory.difficulty_option].text .. ', Capacity: ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '.')
Server.to_discord_embed_raw(CoreData.comfy_emojis.pogkot .. message .. ' Capacity: ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '.')
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.pogkot,message,' Capacity: ',CoreData.capacity_options[memory.capacity_option].text3,'.'}, true)
game.surfaces[CoreData.lobby_surface_name].play_sound{path='utility/new_objective', volume_modifier=0.75}
memory.boat = global_memory.lobby_boats[new_id]
local boat = memory.boat
for _, e in pairs(memory.boat.cannons_temporary_reference or {}) do
Common.new_healthbar(true, e, 2000, nil, e.health, 0.3, -0.1, memory.boat)
Common.new_healthbar(true, e, Balance.cannon_starting_hp, nil, e.health, 0.3, -0.1, memory.boat)
end
boat.dockedposition = boat.position
@ -781,7 +786,7 @@ function Public.summon_crew()
end
end
if print then
Common.notify_force(memory.force, 'Crew summoned.')
Common.notify_force(memory.force, {'pirates.crew_summon'})
end
end
@ -832,10 +837,11 @@ function Public.reset_crew_and_enemy_force(id)
crew_force.mining_drill_productivity_bonus = 1
-- crew_force.mining_drill_productivity_bonus = 1.25
crew_force.manual_mining_speed_modifier = 3
crew_force.character_inventory_slots_bonus = 10
crew_force.character_running_speed_modifier = Balance.base_extra_character_speed
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.laboratory_productivity_bonus = 0
crew_force.ghost_time_to_live = 8 * 60 * 60
crew_force.ghost_time_to_live = 12 * 60 * 60
for k, v in pairs(Balance.player_ammo_damage_modifiers()) do
crew_force.set_ammo_damage_modifier(k, v)
@ -867,12 +873,16 @@ function Public.reset_crew_and_enemy_force(id)
crew_force.recipes['cannon-shell'].enabled = false
crew_force.recipes['explosive-cannon-shell'].enabled = false
--@TRYING this out:
crew_force.technologies['coal-liquefaction'].enabled = true
crew_force.technologies['coal-liquefaction'].researched = true
crew_force.technologies['automobilism'].enabled = false
crew_force.technologies['toolbelt'].enabled = false --trying this. we don't actually want players to carry too many things manually, and in fact in a resource-tight scenario that's problematic
-- note: many of these recipes are overwritten after tech researched!!!!!!! like pistol. check elsewhere in code
crew_force.recipes['pistol'].enabled = false

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Event = require 'utils.event'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Math = require 'maps.pirates.math'
-- local Memory = require 'maps.pirates.memory'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
-- local Utils = require 'maps.pirates.utils_local'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
@ -68,7 +70,7 @@ function Public.new_window(player, name)
flow.style.maximal_width = 270
flow.style.minimal_height = 80
flow.style.natural_height = 80
flow.style.maximal_height = 700
flow.style.maximal_height = 760
flow.style.padding = 10
return flow
@ -405,7 +407,7 @@ function Public.player_and_crew_state_bools(player)
local destination = Common.current_destination()
local dynamic_data = destination.dynamic_data --assumes this always exists
local in_crowsnest_bool, in_hold_bool, in_cabin_bool, onmap_bool, eta_bool, approaching_bool, retreating_bool, atsea_sailing_bool, landed_bool, quest_bool, silo_bool, charged_bool, launched_bool, captain_bool, atsea_loading_bool, character_on_deck_bool, on_deck_standing_near_loco_bool, on_deck_standing_near_cabin_bool, on_deck_standing_near_crowsnest_bool, cost_bool, cost_includes_rocket_launch_bool, approaching_dock_bool, leaving_dock_bool, leave_anytime_bool
local in_crowsnest_bool, in_hold_bool, in_cabin_bool, onmap_bool, eta_bool, approaching_bool, retreating_bool, atsea_sailing_bool, landed_bool, quest_bool, silo_bool, charged_bool, launched_bool, captain_bool, atsea_loading_bool, atsea_waiting_bool, character_on_deck_bool, on_deck_standing_near_loco_bool, on_deck_standing_near_cabin_bool, on_deck_standing_near_crowsnest_bool, cost_bool, cost_includes_rocket_launch_bool, approaching_dock_bool, leaving_dock_bool, leave_anytime_bool
captain_bool = Common.is_captain(player)
@ -423,13 +425,14 @@ function Public.player_and_crew_state_bools(player)
retreating_bool = memory.boat and memory.boat.state == Boats.enum_state.RETREATING and onmap_bool
-- approaching_bool = memory.boat and memory.boat.state == Boats.enum_state.APPROACHING
atsea_sailing_bool = memory.boat and memory.boat.state == Boats.enum_state.ATSEA_SAILING
atsea_waiting_bool = memory.boat and memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL
landed_bool = memory.boat and memory.boat.state == Boats.enum_state.LANDED
quest_bool = (dynamic_data.quest_type ~= nil) and onmap_bool
charged_bool = dynamic_data.silocharged
silo_bool = dynamic_data.rocketsilos and onmap_bool and ((dynamic_data.rocketsilos[1] and dynamic_data.rocketsilos[1].valid) or charged_bool)
launched_bool = dynamic_data.rocketlaunched
cost_bool = destination.static_params.base_cost_to_undock and (not atsea_sailing_bool) and (not retreating_bool)
cost_bool = destination.static_params.base_cost_to_undock and (not atsea_sailing_bool) and (not atsea_waiting_bool) and (not retreating_bool)
cost_includes_rocket_launch_bool = cost_bool and destination.static_params.base_cost_to_undock['launch_rocket']
leave_anytime_bool = (landed_bool and not (eta_bool or cost_bool))
@ -443,11 +446,11 @@ function Public.player_and_crew_state_bools(player)
if character_on_deck_bool then
local BoatData = Boats.get_scope(memory.boat).Data
on_deck_standing_near_loco_bool = Math.distance(player.character.position, Math.vector_sum(memory.boat.position, BoatData.loco_pos)) < 3
on_deck_standing_near_loco_bool = Math.distance(player.character.position, Math.vector_sum(memory.boat.position, BoatData.loco_pos)) < 2.5
on_deck_standing_near_cabin_bool = Math.distance(player.character.position, Math.vector_sum(memory.boat.position, BoatData.cabin_car)) < 2.5
on_deck_standing_near_cabin_bool = Math.distance(player.character.position, Math.vector_sum(memory.boat.position, BoatData.cabin_car)) < 2.0
on_deck_standing_near_crowsnest_bool = Math.distance(player.character.position, Math.vector_sum(memory.boat.position, BoatData.crowsnest_center)) < 2.7
on_deck_standing_near_crowsnest_bool = Math.distance(player.character.position, Math.vector_sum(memory.boat.position, BoatData.crowsnest_center)) < 2.5
end
approaching_dock_bool = destination.type == Surfaces.enum.DOCK and memory.boat.state == Boats.enum_state.APPROACHING
@ -463,6 +466,7 @@ function Public.player_and_crew_state_bools(player)
approaching_bool = approaching_bool,
retreating_bool = retreating_bool,
atsea_sailing_bool = atsea_sailing_bool,
atsea_waiting_bool = atsea_waiting_bool,
-- landed_bool = landed_bool,
quest_bool = quest_bool,
silo_bool = silo_bool,

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
@ -30,7 +32,6 @@ function Public.toggle_window(player)
if not memory.id then return end
flow = GuiCommon.new_window(player, window_name)
flow.caption = 'Crew'
--*** PARAMETERS OF RUN ***--
@ -79,17 +80,17 @@ function Public.toggle_window(player)
flow3 = flow2.add({
name = 'leave_crew',
type = 'button',
caption = 'Quit Crew',
caption = {'pirates.gui_crew_window_buttons_quit_crew'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Return to the lobby.'
flow3.tooltip = {'pirates.gui_crew_window_buttons_quit_crew_tooltip'}
flow3 = flow2.add({
name = 'leave_spectators',
type = 'button',
caption = 'Return to Lobby',
caption = {'pirates.gui_crew_window_buttons_quit_spectators'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
@ -98,7 +99,7 @@ function Public.toggle_window(player)
flow3 = flow2.add({
name = 'spectator_join_crew',
type = 'button',
caption = 'Join Crew',
caption = {'pirates.gui_crew_window_buttons_join_crew'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
@ -107,16 +108,16 @@ function Public.toggle_window(player)
flow3 = flow2.add({
name = 'crewmember_join_spectators',
type = 'button',
caption = 'Spectate',
caption = {'pirates.gui_crew_window_buttons_join_spectators'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'You won\t be able to rejoin the crew for a short while after you do this.'
flow3.tooltip = {'pirates.gui_crew_window_buttons_join_spectators_tooltip'}
--*** MEMBERS AND SPECTATORS ***--
flow2 = GuiCommon.flow_add_section(flow, 'members', 'Crew Members')
flow2 = GuiCommon.flow_add_section(flow, 'members', {'pirates.gui_crew_window_crewmembers'})
flow3 = flow2.add({
name = 'members_listbox',
@ -128,24 +129,25 @@ function Public.toggle_window(player)
flow3 = flow2.add({
name = 'class_renounce',
type = 'button',
caption = 'Give Up Class',
caption = {'pirates.gui_crew_window_crewmembers_give_up_class'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'The class will become available for other crewmembers to take.'
flow3.tooltip = {'pirates.gui_crew_window_crewmembers_give_up_class_tooltip'}
flow3 = flow2.add({
name = 'officer_resign',
type = 'button',
caption = 'Resign as Officer',
caption = {'pirates.gui_crew_window_crewmembers_resign_as_officer'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Give up the officer role.'
flow3.tooltip = {'pirates.gui_crew_window_crewmembers_resign_as_officer_tooltip'}
flow2 = GuiCommon.flow_add_section(flow, 'spectators', {'pirates.gui_crew_window_spectators'})
flow2 = GuiCommon.flow_add_section(flow, 'spectators', 'Spectators')
flow3 = flow2.add({
name = 'spectators_listbox',
@ -156,7 +158,7 @@ function Public.toggle_window(player)
--*** DIFFICULTY VOTE ***--
flow2 = GuiCommon.flow_add_section(flow, 'difficulty_vote', 'Vote for Difficulty')
flow2 = GuiCommon.flow_add_section(flow, 'difficulty_vote', {'pirates.gui_crew_window_vote_for_difficulty'})
for i, o in ipairs(CoreData.difficulty_options) do
flow3 = flow2.add({
@ -171,7 +173,7 @@ function Public.toggle_window(player)
--*** SPARE CLASSES ***--
flow2 = GuiCommon.flow_add_section(flow, 'spare_classes', 'Spare Classes')
flow2 = GuiCommon.flow_add_section(flow, 'spare_classes', {'pirates.gui_crew_window_spare_classes'})
flow3 = flow2.add({
name = 'list',
@ -191,84 +193,84 @@ function Public.toggle_window(player)
})
flow3.style.top_margin = 3
for _, c in ipairs(Classes.Class_List) do
for _, c in pairs(Classes.enum) do
flow4 = flow3.add({
name = 'assign_class_' .. c,
type = 'button',
caption = 'Give class: ' .. Classes.display_form[c],
caption = {'pirates.gui_crew_window_assign_class_button', Classes.display_form(c)},
})
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
flow4.style.font_color = {r=0.10, g=0.10, b=0.10}
flow4.tooltip = 'Give the selected player the class ' .. Classes.display_form[c] .. '.\n\n Class description: ' .. Classes.explanation[c]
flow4.tooltip = {'pirates.gui_crew_window_assign_class_button_tooltip', Classes.display_form(c), Classes.explanation(c)}
-- flow4.tooltip = 'Give this class to the selected player.'
end
for _, c in ipairs(Classes.Class_List) do
for _, c in pairs(Classes.enum) do
flow4 = flow3.add({
name = 'selfassign_class_' .. c,
type = 'button',
caption = 'Take class: ' .. Classes.display_form[c],
caption = {'pirates.gui_crew_window_selfassign_class_button', Classes.display_form(c)},
})
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
flow4.style.font_color = {r=0.10, g=0.10, b=0.10}
flow4.tooltip = 'Give yourself the spare class ' .. Classes.display_form[c] .. '.\n\nClass description: ' .. Classes.explanation[c]
flow4.tooltip = {'pirates.gui_crew_window_selfassign_class_button_tooltip', Classes.display_form(c), Classes.explanation(c)}
end
--*** CAPTAIN's ACTIONS ***--
flow2 = GuiCommon.flow_add_section(flow, 'captain', 'Captain\'s Actions')
flow2 = GuiCommon.flow_add_section(flow, 'captain', {'pirates.gui_crew_window_captains_actions'})
flow3 = flow2.add({
name = 'capn_disband_crew',
type = 'button',
caption = 'Disband Crew',
caption = {'pirates.gui_crew_window_captains_actions_disband_crew'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'End the run. You will be prompted again after clicking.'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_disband_crew_tooltip'}
flow3 = flow2.add({
name = 'capn_disband_are_you_sure',
type = 'button',
caption = 'ARE YOU SURE?',
caption = {'pirates.gui_crew_window_captains_actions_disband_crew_check'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Click to disband the crew.'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_disband_crew_check_tooltip'}
flow3 = flow2.add({
name = 'capn_renounce',
type = 'button',
caption = 'Renounce Captainhood',
caption = {'pirates.gui_crew_window_captains_actions_renounce_title'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'You will no longer be captain, and the role will be passed around until a crewmember takes it.'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_renounce_title_tooltip'}
flow3 = flow2.add({
name = 'capn_pass',
type = 'button',
caption = 'Pass Captain To',
caption = {'pirates.gui_crew_window_captains_actions_pass_title'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Make the selected crewmember into the Captain.'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_pass_title_tooltip'}
flow3 = flow2.add({
name = 'capn_plank',
type = 'button',
caption = 'Plank (Make Spectator)',
caption = {'pirates.gui_crew_window_captains_actions_plank'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'The player will be returned to the lobby and can\'t join your crew for a while. (or use /plank {player})'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_plank_tooltip'}
flow3 = flow2.add({
name = 'line',
@ -291,52 +293,52 @@ function Public.toggle_window(player)
flow3 = flow2.add({
name = 'make_officer',
type = 'button',
caption = 'Make Officer',
caption = {'pirates.gui_crew_window_captains_actions_make_officer'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Make this player an Officer. (or use /officer {player})'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_make_officer_tooltip'}
flow3 = flow2.add({
name = 'unmake_officer',
type = 'button',
caption = 'Unamake Officer',
caption = {'pirates.gui_crew_window_captains_actions_unmake_officer'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Remove this player as an Officer. (or use /officer {player})'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_unmake_officer_tooltip'}
flow3 = flow2.add({
name = 'revoke_class',
type = 'button',
caption = 'Revoke Class',
caption = {'pirates.gui_crew_window_captains_actions_revoke_class'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Put this player\'s class back in the Spare Classes pool.'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_revoke_class_tooltip'}
flow3 = flow2.add({
name = 'capn_summon_crew',
type = 'button',
caption = 'Summon Crew to Ship',
caption = {'pirates.gui_crew_window_captains_actions_summon_crew'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Teleport crewmembers to the ship.'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_summon_crew_tooltip'}
flow3 = flow2.add({
name = 'capn_requisition',
type = 'button',
caption = 'Tax Crew',
caption = {'pirates.gui_crew_window_captains_actions_tax'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'For each non-officer in your crew, take a quarter of their doubloons (and other game-critical items). (or use /tax)'
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_tax_tooltip', Common.coin_tax_percentage}
flow2 = flow.add({
@ -349,7 +351,7 @@ function Public.toggle_window(player)
flow2.style.single_line = false
flow2.style.maximal_width = 190
flow2.style.font = 'default'
flow2.caption = 'To undock, use the top toolbar.'
flow2.caption = {'pirates.gui_crew_window_captains_actions_undock_tip'}
--
@ -388,7 +390,7 @@ function Public.full_update(player)
local other_player_selected = flow.members.body.members_listbox.selected_index ~= 0 and tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2]) ~= player.index
local any_class_button = false
for _, c in pairs(Classes.Class_List) do
for _, c in pairs(Classes.enum) do
if memory.spare_classes and Utils.contains(memory.spare_classes, c) and (not (player.controller_type == defines.controllers.spectator)) then
if Common.is_captain(player) and memory.crewplayerindices and #memory.crewplayerindices > 1 then
if other_player_selected and (not (memory.classes_table[tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])])) then
@ -468,18 +470,21 @@ function Public.full_update(player)
if memory.id then
flow.caption = memory.name
flow.crew_age.caption = 'Age: ' .. Utils.time_mediumform((memory.age or 0)/60)
-- flow.crew_difficulty.caption = 'Difficulty: ' .. CoreData.difficulty_options[memory.difficulty_option].text
flow.crew_capacity_and_difficulty.caption = CoreData.difficulty_options[memory.difficulty_option].text .. ', Capacity ' .. CoreData.capacity_options[memory.capacity_option].text
flow.crew_age.caption = {'pirates.gui_crew_window_crew_age', Utils.time_mediumform((memory.age or 0)/60)}
flow.crew_capacity_and_difficulty.caption = {'pirates.gui_crew_window_crew_capacity_and_difficulty', CoreData.difficulty_options[memory.difficulty_option].text, CoreData.capacity_options[memory.capacity_option].text3}
if flow.spare_classes.visible then
local str = ''
local str = {''}
for i, c in ipairs(memory.spare_classes) do
if i>1 then str = str .. ', ' end
str = str .. Classes.display_form[c]
if i>1 then
str[#str+1] = {'', {'pirates.separator_1'}, Classes.display_form(c)} -- we need to do nesting here, because you can't contanenate more than 20 localised strings. Watch out!
--@TODO: In fact we should nest iteratively, as this still caps out around 19 classes.
else
str[#str+1] = {'', Classes.display_form(c)}
end
end
str = str .. '.'
str[#str+1] = '.'
flow.spare_classes.body.list.caption = str
end
@ -496,7 +501,7 @@ function Public.full_update(player)
end
GuiCommon.update_listbox(flow.members.body.members_listbox, wrappedcrew)
flow.members.header.caption = 'Crew Members (' .. (#memory.crewplayerindices or 0) .. ')'
flow.members.header.caption = {'pirates.gui_crew_window_crew_count', (#memory.crewplayerindices or 0)}
end
if flow.spectators.visible then
@ -561,12 +566,12 @@ function Public.click(event)
if string.sub(eventname, 1, 13) and string.sub(eventname, 1, 13) == 'assign_class_' then
local other_id = tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])
Classes.assign_class(other_id, tonumber(string.sub(eventname, 14, -1)))
Classes.assign_class(other_id, string.sub(eventname, 14, -1))
return
end
if string.sub(eventname, 1, 17) and string.sub(eventname, 1, 17) == 'selfassign_class_' then
Classes.assign_class(player.index, tonumber(string.sub(eventname, 18, -1)), true)
Classes.assign_class(player.index, string.sub(eventname, 18, -1), true)
return
end
@ -621,9 +626,9 @@ function Public.click(event)
if Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN then
local force = memory.force
if force and force.valid then
local message = player.name .. ' disbanded ' .. memory.name .. ', after ' .. Utils.time_longform((memory.real_age or 0)/60) .. '.'
local message = {'pirates.crew_disbanded', player.name, memory.name, Utils.time_longform((memory.real_age or 0)/60)}
Common.notify_game(message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.trashbin .. '[' .. memory.name .. '] ' .. message)
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.trashbin .. '[' .. memory.name .. '] ',message}, true)
end
Crew.disband_crew(true)
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Common = require 'maps.pirates.common'
local Balance = require 'maps.pirates.balance'
@ -79,9 +81,7 @@ function Public.full_update(player)
local types = {'leagues', 'kraken', 'time', 'silo', 'nests', 'sandwurms'}
local str = 'Local biter evolution: '
if memory.boat and memory.boat.state and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
if memory.boat and memory.boat.state and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
evolution_leagues = evo - (memory.kraken_evo or 0)
local krakens = false
if memory.active_sea_enemies and memory.active_sea_enemies.krakens then
@ -106,31 +106,36 @@ function Public.full_update(player)
evolution_total = (evolution_leagues or 0) + (evolution_time or 0) + (evolution_nests or 0) + (evolution_silo or 0) + (evolution_sandwurms or 0)
end
str = str .. string.format('%.2f\n', evolution_total)
local str = {'',{'pirates.gui_evo_tooltip_1', string.format('%.2f', evolution_total)}}
if evolution_leagues or evolution_time or evolution_nests or evolution_silo or evolution_sandwurms then
str[#str+1] = {'','\n'}
end
for _, type in ipairs(types) do
if type == 'leagues' then
if evolution_leagues then
str = str .. string.format('\nLeagues: %.2f', evolution_leagues)
str[#str+1] = {'','\n',{'pirates.gui_evo_tooltip_2', string.format('%.2f', evolution_leagues)}}
end
elseif type == 'kraken' then
if evolution_kraken then
str = str .. string.format('\nKraken: %.2f', evolution_kraken)
str[#str+1] = {'','\n',{'pirates.gui_evo_tooltip_3', string.format('%.2f', evolution_kraken)}}
end
elseif type == 'time' then
if evolution_time then
str = str .. string.format('\nTime: %.2f', evolution_time)
str[#str+1] = {'','\n',{'pirates.gui_evo_tooltip_4', string.format('%.2f', evolution_time)}}
end
elseif type == 'silo' then
if evolution_silo then
str = str .. string.format('\nSilo: %.2f', evolution_silo)
str[#str+1] = {'','\n',{'pirates.gui_evo_tooltip_5', string.format('%.2f', evolution_silo)}}
end
elseif type == 'nests' then
if evolution_nests then
str = str .. string.format('\nNests: %.2f', evolution_nests)
str[#str+1] = {'','\n',{'pirates.gui_evo_tooltip_6', string.format('%.2f', evolution_nests)}}
end
elseif type == 'sandwurms' then
if evolution_sandwurms then
str = str .. string.format('\nSandwurms: %.2f', evolution_sandwurms)
str[#str+1] = {'','\n',{'pirates.gui_evo_tooltip_7', string.format('%.2f', evolution_sandwurms)}}
end
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Common = require 'maps.pirates.common'

View File

@ -1,3 +1,4 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -77,15 +78,15 @@ local function create_gui(player)
flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'info_piratebutton')
flow2.caption = '?'
flow2.style.font = 'debug'
flow2.tooltip = 'Notes and updates on Pirate Ship'
flow2.tooltip = {'pirates.gui_info_main_tooltip'}
flow2.style.font_color = {r=1, g=1, b=1}
flow2.style.hovered_font_color = {r=1, g=1, b=1}
flow2.style.clicked_font_color = {r=1, g=1, b=1}
flow2.parent.style.left_padding = -6
flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'runs_piratebutton', 70)
flow2.caption = 'Crews'
flow2.tooltip = 'View the ongoing runs, and make proposals for new ones.'
flow2.caption = {'pirates.gui_crews'}
flow2.tooltip = {'pirates.gui_crews_main_tooltip'}
flow2.style.font = 'debug'
flow2.style.font_color = {r=1, g=1, b=1}
flow2.style.hovered_font_color = {r=1, g=1, b=1}
@ -119,10 +120,10 @@ local function create_gui(player)
flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'evo_piratebutton')
flow2.sprite = 'entity/small-biter'
flow2.mouse_button_filter = {'middle'} --hack to avoid press visual
flow2.show_percent_for_small_numbers = true
flow2.show_percent_for_small_numbers = true --as of factorio v1.1.59, there is a bug in which 1.002 displays as like 1e-2% or something. but after 1.01 it's ok
flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'minimap_piratebutton')
flow2.tooltip = 'View the outside world.'
flow2.tooltip = {'pirates.gui_minimap_main_tooltip'}
flow2.sprite = 'utility/map'
-- flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'shop_piratebutton')
@ -154,7 +155,7 @@ local function create_gui(player)
})
flow3.style.font = 'default-large-semibold'
flow3.style.font_color = GuiCommon.bold_font_color
flow3.caption = 'Fuel:'
flow3.caption = {'pirates.gui_fuel_1'}
flow3 = flow2.add({
name = 'fuel_label_1',
@ -516,7 +517,7 @@ function Public.process_etaframe_update(player, flow1, bools)
local flow2
if bools.cost_bool or bools.atsea_loading_bool or bools.eta_bool or bools.retreating_bool or bools.leave_anytime_bool then
if bools.cost_bool or bools.atsea_loading_bool or bools.atsea_waiting_bool or bools.eta_bool or bools.retreating_bool or bools.leave_anytime_bool then
flow1.visible = true
local tooltip = ''
@ -531,9 +532,9 @@ function Public.process_etaframe_update(player, flow1, bools)
flow2.etaframe_label_1.visible = true
flow2.etaframe_label_2.visible = false
tooltip = 'Probably time to board...'
tooltip = {'pirates.gui_etaframe_board_warning_tooltip'}
flow2.etaframe_label_1.caption = 'RETURN TO SHIP'
flow2.etaframe_label_1.caption = {'pirates.gui_etaframe_board_warning'}
elseif bools.eta_bool then
flow2.etaframe_label_1.visible = true
@ -543,7 +544,7 @@ function Public.process_etaframe_update(player, flow1, bools)
local passive_eta = dynamic_data.time_remaining
flow2.etaframe_label_1.caption = 'Auto-undock:'
flow2.etaframe_label_1.caption = {'pirates.gui_etaframe_autoundock'}
flow2.etaframe_label_2.caption = Utils.standard_string_form_of_time_in_seconds(passive_eta)
elseif bools.atsea_loading_bool then
@ -561,16 +562,25 @@ function Public.process_etaframe_update(player, flow1, bools)
local eta_ticks = total + (memory.extra_time_at_sea or 0) - memory.loadingticks
flow2.etaframe_label_1.caption = 'Arriving in'
flow2.etaframe_label_1.caption = {'pirates.gui_etaframe_arriving_in'}
flow2.etaframe_label_2.caption = Utils.standard_string_form_of_time_in_seconds(eta_ticks / 60)
elseif bools.atsea_waiting_bool then
flow2.etaframe_label_1.visible = true
flow2.etaframe_label_2.visible = false
tooltip = {'pirates.atsea_waiting_tooltip'}
flow2.etaframe_label_1.caption = {'pirates.gui_etaframe_atsea_waiting'}
elseif bools.leave_anytime_bool then
flow2.etaframe_label_1.visible = true
flow2.etaframe_label_2.visible = true
tooltip = {'pirates.leave_anytime_tooltip'}
flow2.etaframe_label_1.caption = 'Undock:'
flow2.etaframe_label_2.caption = 'Anytime'
flow2.etaframe_label_1.caption = {'pirates.gui_etaframe_undock'}
flow2.etaframe_label_2.caption = {'pirates.gui_etaframe_anytime'}
end
if bools.cost_bool then
@ -589,14 +599,14 @@ function Public.process_etaframe_update(player, flow1, bools)
-- local caption
if bools.atsea_loading_bool then
if memory.overworldx >= Balance.rockets_needed_x then --bools.eta_bool is not helpful yet
flow2.etaframe_label_3.caption = 'Next escape cost:'
flow2.etaframe_label_3.caption = {'pirates.gui_etaframe_nest_escape_cost'}
if bools.cost_includes_rocket_launch_bool then
tooltip = {'pirates.resources_needed_tooltip_0_rocketvariant'}
else
tooltip = {'pirates.resources_needed_tooltip_0'}
end
else
flow2.etaframe_label_3.caption = 'Next escape cost:'
flow2.etaframe_label_3.caption = {'pirates.gui_etaframe_nest_escape_cost'}
if bools.cost_includes_rocket_launch_bool then
tooltip = {'pirates.resources_needed_tooltip_1_rocketvariant'}
else
@ -606,7 +616,7 @@ function Public.process_etaframe_update(player, flow1, bools)
elseif (not bools.eta_bool) then
flow2.etaframe_label_3.visible = false
flow2.etaframe_label_1.visible = true
flow2.etaframe_label_1.caption = 'To escape, store'
flow2.etaframe_label_1.caption = {'pirates.gui_etaframe_to_escape_store'}
if bools.cost_includes_rocket_launch_bool then
tooltip = {'pirates.resources_needed_tooltip_3_rocketvariant'}
@ -614,7 +624,7 @@ function Public.process_etaframe_update(player, flow1, bools)
tooltip = {'pirates.resources_needed_tooltip_3'}
end
else
flow2.etaframe_label_3.caption = 'Or store'
flow2.etaframe_label_3.caption = {'pirates.gui_etaframe_or_store'}
local adjusted_costs_resources_strings = Common.time_adjusted_departure_cost_resources_strings(memory)
if bools.cost_includes_rocket_launch_bool then
@ -648,7 +658,7 @@ function Public.process_etaframe_update(player, flow1, bools)
else
cost_table['cost_launch_rocket'].number = 0
end
cost_table['cost_launch_rocket'].tooltip = 'Launch a rocket'
cost_table['cost_launch_rocket'].tooltip = {'pirates.gui_etaframe_rocket_requirement_tooltip'}
cost_table['cost_launch_rocket'].visible = true
else
cost_table['cost_launch_rocket'].visible = false
@ -658,11 +668,11 @@ function Public.process_etaframe_update(player, flow1, bools)
flow1.etaframe_piratebutton.tooltip = tooltip
flow2.tooltip = tooltip
if bools.captain_bool and (not bools.retreating_bool) and (bools.leave_anytime_bool or bools.eta_bool or (bools.cost_bool and (not bools.atsea_loading_bool))) then
if bools.captain_bool and (not bools.retreating_bool) and (bools.leave_anytime_bool or bools.atsea_waiting_bool or bools.eta_bool or (bools.cost_bool and (not bools.atsea_loading_bool))) then
flow1.etaframe_piratebutton.mouse_button_filter = {'left'}
if memory.undock_shortcut_are_you_sure_data and memory.undock_shortcut_are_you_sure_data[player.index] and memory.undock_shortcut_are_you_sure_data[player.index] > game.tick - 60 * 4 then
flow2.etaframe_label_1.visible = true
flow2.etaframe_label_1.caption = 'Undock — Are you sure?'
flow2.etaframe_label_1.caption = {'pirates.gui_etaframe_undock_are_you_sure'}
flow2.etaframe_label_2.visible = false
flow2.etaframe_label_3.visible = false
end
@ -699,23 +709,23 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
flow1.silo_label_3.visible = true
-- flow1.silo_label_1.caption = string.format('[achievement=there-is-no-spoon]: +%.0f[item=sulfur]', dynamic_data.rocketcoalreward)
flow1.silo_label_1.caption = string.format('Launched:')
flow1.silo_label_1.caption = {'pirates.gui_etaframe_launched'}
-- flow1.silo_label_1.caption = string.format('Launched for %.0f[item=coal] , ' .. Balance.rocket_launch_coin_reward .. '[item=coin]', dynamic_data.rocketcoalreward)
flow1.silo_label_1.style.font_color = GuiCommon.achieved_font_color
flow1.silo_label_3.caption = Math.floor(dynamic_data.rocketcoalreward/100)/10 .. 'k[item=coal], ' .. Math.floor(Balance.rocket_launch_coin_reward/100)/10 .. 'k[item=coin]'
local tooltip = 'This island\'s rocket has launched, and this is the reward.'
local tooltip = {'pirates.gui_etaframe_launched_tooltip'}
flow1.tooltip = tooltip
flow1.silo_label_1.tooltip = tooltip
flow1.silo_label_3.tooltip = tooltip
else
local tooltip = 'The rocket is launching...'
local tooltip = {'pirates.gui_etaframe_launching'}
flow1.tooltip = tooltip
flow1.silo_label_1.tooltip = tooltip
flow1.silo_progressbar.tooltip = tooltip
flow1.silo_label_1.caption = 'Charge:'
flow1.silo_label_1.caption = {'pirates.gui_etaframe_charge'}
flow1.silo_label_1.style.font_color = GuiCommon.bold_font_color
flow1.silo_label_2.visible = false
flow1.silo_label_3.visible = false
@ -725,7 +735,7 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
end
else
flow1.silo_label_1.caption = 'Charge:'
flow1.silo_label_1.caption = {'pirates.gui_etaframe_charge'}
flow1.silo_label_1.style.font_color = GuiCommon.bold_font_color
flow1.silo_label_2.visible = true
flow1.silo_progressbar.visible = true
@ -737,7 +747,7 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
flow1.silo_progressbar.value = consumed/needed
local tooltip = string.format('Rocket silo charge: %.1f/%.1f GJ\n\nFully charge the silo to launch a rocket, gaining both doubloons and fuel.', Math.floor(consumed / 100000000)/10, Math.floor(needed / 100000000)/10)
local tooltip = {'pirates.gui_etaframe_charge_tooltip', string.format('%.1f', Math.floor(consumed / 100000000)/10), string.format('%.1f', Math.floor(needed / 100000000)/10)}
flow1.tooltip = tooltip
flow1.silo_label_1.tooltip = tooltip
flow1.silo_label_2.tooltip = tooltip
@ -778,8 +788,8 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
local tooltip = ''
if quest_complete and quest_reward then
tooltip = 'This island\'s quest is complete, and this is the reward.'
flow1.quest_label_1.caption = 'Island Quest:'
tooltip = {'pirates.gui_questframe_complete_tooltip'}
flow1.quest_label_1.caption = {'pirates.gui_questframe'}
flow1.quest_label_1.style.font_color = GuiCommon.achieved_font_color
flow1.quest_label_2.visible = true
flow1.quest_label_3.visible = false
@ -787,7 +797,7 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
flow1.quest_label_2.caption = quest_reward.display_amount .. ' ' .. quest_reward.display_sprite
elseif quest_reward then
if quest_progress < quest_progressneeded then
flow1.quest_label_1.caption = 'Island Quest:'
flow1.quest_label_1.caption = {'pirates.gui_questframe'}
flow1.quest_label_1.style.font_color = GuiCommon.bold_font_color
flow1.quest_label_2.visible = true
flow1.quest_label_3.visible = true
@ -801,7 +811,7 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
end
if quest_type == Quest.enum.TIME then
if tooltip == '' then tooltip = 'Island Quest: Time\n\nLaunch a rocket before the countdown completes for a bonus.' end
if tooltip == '' then tooltip = {'pirates.gui_questframe_time'} end
if quest_progress >= 0 then
flow1.quest_label_3.caption = string.format('%.0fm%.0fs', Math.floor(quest_progress / 60), quest_progress % 60)
@ -819,18 +829,18 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
end
end
else
flow1.quest_label_3.caption = string.format('Fail')
flow1.quest_label_3.caption = {'pirates.gui_questframe_fail'}
flow1.quest_label_3.style.font_color = GuiCommon.insufficient_font_color
end
elseif quest_type == Quest.enum.WORMS then
if tooltip == '' then tooltip = 'Island Quest: Worms\n\nKill enough worms for a bonus.' end
if tooltip == '' then tooltip = {'pirates.gui_questframe_worms'} end
elseif quest_type == Quest.enum.FIND then
if tooltip == '' then tooltip = 'Island Quest: Ghosts\n\nFind the ghosts for a bonus.' end
if tooltip == '' then tooltip = {'pirates.gui_questframe_find'} end
elseif quest_type == Quest.enum.RESOURCEFLOW then
if tooltip == '' then tooltip = 'Island Quest: Resource Flow\n\nAchieve a production rate of a particular item for a bonus.' end
if tooltip == '' then tooltip = {'pirates.gui_questframe_resourceflow'} end
-- out of date:
if quest_progressneeded/60 % 1 == 0 then
@ -842,18 +852,18 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
end
elseif quest_type == Quest.enum.RESOURCECOUNT then
if tooltip == '' then tooltip = 'Island Quest: Item Production\n\nSimply complete production of these items for a bonus, anywhere on the map.' end
if tooltip == '' then tooltip = {'pirates.gui_questframe_resourcecount'} end
flow1.quest_label_2.caption = string.format('%s ', '[item=' .. quest_params.item .. ']')
elseif quest_type == Quest.enum.NODAMAGE then
if tooltip == '' then tooltip = 'Island Quest: No Damage\n\nLaunch a rocket without the silo taking damage.' end
if tooltip == '' then tooltip = {'pirates.gui_questframe_nodamage'} end
if bools.approaching_bool or (dynamic_data.rocketsilos and dynamic_data.rocketsilos[1] and dynamic_data.rocketsilos[1].valid and dynamic_data.rocketsilohp == dynamic_data.rocketsilomaxhp) then
flow1.quest_label_3.caption = string.format('OK')
flow1.quest_label_3.caption = {'pirates.gui_questframe_ok'}
flow1.quest_label_3.style.font_color = GuiCommon.sufficient_font_color
else
flow1.quest_label_3.caption = string.format('Fail')
flow1.quest_label_3.caption = {'pirates.gui_questframe_fail'}
flow1.quest_label_3.style.font_color = GuiCommon.insufficient_font_color
end
end
@ -893,10 +903,10 @@ function Public.update_gui(player)
flow1 = pirates_flow.crew_piratebutton_frame.crew_piratebutton
if memory.id and memory.id ~= 0 then
flow1.tooltip = 'Your Crew\n\nPerform crew actions, such as selecting a class if any are available.'
flow1.tooltip = {'pirates.gui_crew_tooltip_1'}
flow1.mouse_button_filter = {'left','right'}
else
flow1.tooltip = 'Your Crew\n\nYou\'re a free agent, so there\'s nothing to do here.'
flow1.tooltip = {'pirates.gui_crew_tooltip_2'}
flow1.mouse_button_filter = {'middle'} --hack to avoid press visual
if player.gui.screen['crew_piratewindow'] then
player.gui.screen['crew_piratewindow'].destroy()
@ -937,7 +947,7 @@ function Public.update_gui(player)
flow2.fuel_label_1.caption = Utils.bignumber_abbrevform(memory.stored_fuel or 0) .. '[item=coal]'
flow2.fuel_label_2.caption = Utils.negative_rate_abbrevform(memory.fuel_depletion_rate_memoized or 0)
local color_scale = Math.max(Math.min((- (memory.fuel_depletion_rate_memoized or 0))/30, 1),0)
local color_scale = Math.clamp(0, 1, (- (memory.fuel_depletion_rate_memoized or 0))/30)
flow2.fuel_label_2.style.font_color = {
r = GuiCommon.fuel_color_1.r * (1-color_scale) + GuiCommon.fuel_color_2.r * color_scale,
g = GuiCommon.fuel_color_1.g * (1-color_scale) + GuiCommon.fuel_color_2.g * color_scale,
@ -951,7 +961,7 @@ function Public.update_gui(player)
flow1 = pirates_flow.progress_piratebutton_frame.progress_piratebutton
flow1.number = (memory.overworldx or 0)
flow1.caption = string.format('Progress: %d leagues.\n\nTravel %d leagues to win the game.', memory.overworldx or 0, CoreData.victory_x)
flow1.caption = {'pirates.gui_progress_tooltip', memory.overworldx or 0, CoreData.victory_x}
-- pirates_flow.destination_piratebutton_frame.destination_piratebutton.number = memory.destinationsvisited_indices and #memory.destinationsvisited_indices or 0
@ -1069,7 +1079,7 @@ function Public.update_gui(player)
if flow1 then
-- if not bools.eta_bool and not bools.retreating_bool and not bools.quest_bool and not bools.silo_bool and not bools.atsea_loading_bool and not bools.leave_anytime_bool and not bools.cost_bool and not bools.approaching_dock_bool and not bools.leaving_dock_bool then
if not bools.eta_bool and not bools.retreating_bool and not bools.quest_bool and not bools.silo_bool and not bools.atsea_loading_bool and not bools.leave_anytime_bool and not bools.cost_bool and not bools.approaching_dock_bool and not bools.leaving_dock_bool and not bools.atsea_sailing_bool then
if not (bools.eta_bool or bools.retreating_bool or bools.quest_bool or bools.silo_bool or bools.atsea_loading_bool or bools.leave_anytime_bool or bools.cost_bool or bools.approaching_dock_bool or bools.leaving_dock_bool or bools.atsea_sailing_bool or bools.atsea_waiting_bool) then
flow1.visible = true
else
flow1.visible = false
@ -1080,7 +1090,7 @@ function Public.update_gui(player)
flow1 = pirates_flow.minimap_piratebutton_frame
if flow1 then
if bools.in_hold_bool then
if bools.in_hold_bool or bools.in_cabin_bool then
flow1.visible = true
else
flow1.visible = false
@ -1109,17 +1119,17 @@ function Public.update_gui(player)
if bools.on_deck_standing_near_loco_bool then
flow1.visible = true
flow1.surface_index = Hold.get_hold_surface(1).index
flow1.zoom = 0.18
flow1.style.minimal_height = 268
flow1.style.minimal_width = 532
flow1.position = {x=0,y=0}
flow1.zoom = 0.182
flow1.style.minimal_height = 292
flow1.style.minimal_width = 540
flow1.position = {x=0,y=-2}
elseif bools.on_deck_standing_near_cabin_bool then
flow1.visible = true
flow1.surface_index = Cabin.get_cabin_surface().index
flow1.zoom = 0.468
flow1.style.minimal_height = 416
flow1.style.minimal_width = 260
flow1.position = {x=0,y=-1.3}
flow1.style.minimal_height = 400
flow1.style.minimal_width = 280
flow1.position = {x=0,y=-1}
elseif bools.on_deck_standing_near_crowsnest_bool then
flow1.visible = true
flow1.surface_index = Crowsnest.get_crowsnest_surface().index
@ -1127,7 +1137,7 @@ function Public.update_gui(player)
flow1.style.minimal_height = 384
flow1.style.minimal_width = 384
flow1.position = {x=memory.overworldx,y=memory.overworldy}
elseif bools.in_cabin_bool or bools.in_crowsnest_bool then
elseif bools.in_crowsnest_bool then
flow1.visible = true
flow1.surface_index = game.surfaces[memory.boat.surface_name].index
flow1.zoom = 0.09
@ -1158,19 +1168,27 @@ local function on_gui_click(event)
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if event.element.name and event.element.name == 'etaframe_piratebutton' and (memory.boat.state == Boats.enum_state.DOCKED or memory.boat.state == Boats.enum_state.LANDED) then
if Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN then
if (not memory.undock_shortcut_are_you_sure_data) then memory.undock_shortcut_are_you_sure_data = {} end
if memory.undock_shortcut_are_you_sure_data[player.index] and memory.undock_shortcut_are_you_sure_data[player.index] > game.tick - 60 * 4 then
if memory.boat.state == Boats.enum_state.DOCKED then
Progression.undock_from_dock(true)
elseif memory.boat.state == Boats.enum_state.LANDED then
Progression.try_retreat_from_island(player, true)
if event.element.name and event.element.name == 'etaframe_piratebutton' then
if (memory.boat.state == Boats.enum_state.DOCKED or memory.boat.state == Boats.enum_state.LANDED) then
if Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN then
if (not memory.undock_shortcut_are_you_sure_data) then memory.undock_shortcut_are_you_sure_data = {} end
if memory.undock_shortcut_are_you_sure_data[player.index] and memory.undock_shortcut_are_you_sure_data[player.index] > game.tick - 60 * 4 then
if memory.boat.state == Boats.enum_state.DOCKED then
Progression.undock_from_dock(true)
elseif memory.boat.state == Boats.enum_state.LANDED then
Progression.try_retreat_from_island(player, true)
end
else
memory.undock_shortcut_are_you_sure_data[player.index] = game.tick
end
else
memory.undock_shortcut_are_you_sure_data[player.index] = game.tick
end
elseif memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL then
if Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN then
Progression.at_sea_begin_to_set_sail()
end
end
elseif string.sub(event.element.name, -13, -1) and string.sub(event.element.name, -13, -1) == '_piratebutton' then
local name = string.sub(event.element.name, 1, -14)
if Public[name] then

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
-- local Common = require 'maps.pirates.common'
@ -36,7 +38,7 @@ function Public.toggle_window(player)
flow.style.width = width
flow.style.height = 420
flow2 = Public.flow_add_info_tab(flow, 'Info')
flow2 = Public.flow_add_info_tab(flow, {'pirates.gui_info_info'})
flow3 = flow2.parent.last_info_flow_1.last_info_flow_2
flow4 = flow3.add{type = "label", caption = {"pirates.softmod_info_body_1"}}
@ -49,16 +51,16 @@ function Public.toggle_window(player)
Public.flow_add_info_sections(flow2, {'game_description'})
flow2 = Public.flow_add_info_tab(flow, 'Updates')
flow2 = Public.flow_add_info_tab(flow, {'pirates.gui_info_updates'})
Public.flow_add_info_sections(flow2, {'updates'})
-- Public.flow_add_info_sections(flow2, {'updates', 'bugs'})
flow2 = Public.flow_add_info_tab(flow, 'Tips')
flow2 = Public.flow_add_info_tab(flow, {'pirates.gui_info_tips'})
Public.flow_add_info_sections(flow2, {'new_players', 'tips'})
flow2 = Public.flow_add_info_tab(flow, 'Credits')
flow2 = Public.flow_add_info_tab(flow, {'pirates.gui_info_credits'})
Public.flow_add_info_sections(flow2, {'credits'})
end
@ -224,11 +226,11 @@ function Public.full_update(player)
if flow2.selected_tab_index == 1 then
flow2.style.height = 400
elseif flow2.selected_tab_index == 2 then
flow2.style.height = 420
flow2.style.height = 570
elseif flow2.selected_tab_index == 3 then
flow2.style.height = 685
flow2.style.height = 580
elseif flow2.selected_tab_index == 4 then
flow2.style.height = 360
flow2.style.height = 340
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
@ -37,7 +39,7 @@ function Public.toggle_window(player)
end -- else:
flow = GuiCommon.new_window(player, window_name)
flow.caption = 'Outside View'
flow.caption = {'pirates.gui_minimap_outside_view'}
flow.style.maximal_width = 800
local memory = Memory.get_crew_memory()
@ -86,7 +88,7 @@ function Public.toggle_window(player)
position = position,
surface_index = game.surfaces[memory.boat.surface_name].index,
zoom = zoom,
tooltip = 'LMB: Zoom in.\nRMB: Zoom out.\nMMB: Scale window.'
tooltip = {'pirates.gui_minimap_tooltip'}
}
)
element.style.margin = 1
@ -104,8 +106,8 @@ function Public.toggle_window(player)
index = 1,
allow_none_state = false,
switch_state = switch_state,
left_label_caption = 'Auto Show Map — On',
right_label_caption = 'Off'
left_label_caption = {'pirates.gui_minimap_switch_left'},
right_label_caption = {'pirates.gui_minimap_switch_right'},
}
)
end
@ -201,8 +203,8 @@ function Public.click(event)
elseif size == 440 then
size = 560
elseif size == 560 then
size = 700
elseif size == 700 then
size = 660
elseif size == 660 then
size = 280
else
size = 340
@ -227,14 +229,14 @@ local function on_player_changed_surface(event)
local window = player.gui.screen[window_name .. '_piratewindow']
local from_hold_bool = string.sub(game.surfaces[event.surface_index].name, 9, 12) == 'Hold'
local to_hold_bool = string.sub(player.surface.name, 9, 12) == 'Hold'
local from_hold_or_cabin_bool = string.sub(game.surfaces[event.surface_index].name, 9, 12) == 'Hold' or string.sub(game.surfaces[event.surface_index].name, 9, 13) == 'Cabin'
local to_hold_or_cabin_bool = string.sub(player.surface.name, 9, 12) == 'Hold' or string.sub(player.surface.name, 9, 13) == 'Cabin'
if from_hold_bool and (not to_hold_bool) then
if from_hold_or_cabin_bool and (not to_hold_or_cabin_bool) then
if window then
Public.toggle_window(player)
end
elseif to_hold_bool and (not from_hold_bool) then
elseif to_hold_or_cabin_bool and (not from_hold_or_cabin_bool) then
local global_memory = Memory.get_global_memory()
local gui_memory = global_memory.player_gui_memories[player.index]

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
@ -20,9 +22,9 @@ function Public.toggle_window(player)
local flow, flow2, flow3
flow = GuiCommon.new_window(player, window_name)
flow.caption = 'Progress'
flow.caption = {'pirates.gui_progress'}
flow2 = GuiCommon.flow_add_section(flow, 'distance_travelled', 'Distance Travelled:')
flow2 = GuiCommon.flow_add_section(flow, 'distance_travelled', {'pirates.gui_progress_distance_travelled'})
flow3 = flow2.add({
name = 'leagues',
@ -35,7 +37,7 @@ function Public.toggle_window(player)
flow3.style.maximal_width = 160
flow3.style.font = 'default-dropdown'
flow2 = GuiCommon.flow_add_section(flow, 'current_location', 'Current location: ')
flow2 = GuiCommon.flow_add_section(flow, 'current_location', {'pirates.gui_progress_current_location', ''})
-- flow3 = flow2.add({
-- name = 'location_name',
@ -107,8 +109,8 @@ function Public.full_update(player)
name = Lobby.Data.display_name
end
flow.current_location.header.caption = string.format('Current location: %s', name)
flow.distance_travelled.body.leagues.caption = string.format('%d leagues', memory.overworldx or 0)
flow.current_location.header.caption = {'pirates.gui_progress_current_location', name}
flow.distance_travelled.body.leagues.caption = {'pirates.gui_progress_leagues', memory.overworldx or 0}
-- local daynighttype
-- if destination.static_params and destination.static_params.daynightcycletype then
@ -143,7 +145,7 @@ function Public.full_update(player)
-- flow.current_location.body.daynight.visible = false
-- end
local daynightcycletype = destination.static_params.daynightcycletype or 1
flow.current_location.body.daynight.caption = 'Time of day: ' .. CoreData.daynightcycle_types[daynightcycletype].displayname
flow.current_location.body.daynight.caption = {'pirates.gui_progress_time_of_day', CoreData.daynightcycle_types[daynightcycletype].displayname}
-- local ores

View File

@ -1,3 +1,4 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
@ -168,16 +169,16 @@ function Public.toggle_window(player)
if player.gui.screen[window_name .. '_piratewindow'] then player.gui.screen[window_name .. '_piratewindow'].destroy() return end
flow = GuiCommon.new_window(player, window_name)
flow.caption = 'Play'
flow.caption = {'pirates.gui_runs_play'}
--*** ONGOING RUNS ***--
flow2 = GuiCommon.flow_add_section(flow, 'ongoing_runs', 'Ongoing Runs')
flow2 = GuiCommon.flow_add_section(flow, 'ongoing_runs', {'pirates.gui_runs_ongoing_runs'})
flow3 = flow2.add({
name = 'helpful_tip',
type = 'label',
caption = 'To join a run, first select it in the table below.',
caption = {'pirates.gui_runs_ongoing_runs_helpful_tip'},
})
flow3.style.font_color = {r=0.90, g=0.90, b=0.90}
flow3.style.single_line = false
@ -199,7 +200,7 @@ function Public.toggle_window(player)
flow4 = flow3.add({
name = 'join_spectators',
type = 'button',
caption = 'Spectate',
caption = {'pirates.gui_runs_ongoing_runs_spectate'},
})
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
@ -208,7 +209,7 @@ function Public.toggle_window(player)
flow4 = flow3.add({
name = 'join_crew',
type = 'button',
caption = 'Join Crew',
caption = {'pirates.gui_runs_ongoing_runs_join_crew'},
})
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
@ -217,7 +218,7 @@ function Public.toggle_window(player)
flow4 = flow3.add({
name = 'leave_spectators',
type = 'button',
caption = 'Return to Lobby',
caption = {'pirates.gui_runs_ongoing_runs_return_to_lobby'},
})
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
@ -232,14 +233,14 @@ function Public.toggle_window(player)
flow3 = flow2.add({
name = 'leaving_prompt',
type = 'label',
caption = 'Hop on board.',
caption = {'pirates.gui_runs_ongoing_runs_hop_on_board'},
})
flow3.style.left_margin = 5
-- PROPOSALS --
flow2 = GuiCommon.flow_add_section(flow, 'proposals', 'Proposals')
flow2 = GuiCommon.flow_add_section(flow, 'proposals', {'pirates.gui_runs_proposals'})
flow3 = flow2.add({
name = 'proposals_listbox',
@ -256,7 +257,7 @@ function Public.toggle_window(player)
flow4 = flow3.add({
name = 'endorse_proposal',
type = 'button',
caption = 'Endorse Proposal',
caption = {'pirates.gui_runs_proposals_endorse_proposal'},
})
flow4.style.minimal_width = 150
flow4.style.font = 'default-bold'
@ -266,7 +267,7 @@ function Public.toggle_window(player)
flow4 = flow3.add({
name = 'retract_endorsement',
type = 'button',
caption = 'Retract Endorsement',
caption = {'pirates.gui_runs_proposals_retract_endorsement'},
})
flow4.style.minimal_width = 150
flow4.style.font = 'default-bold'
@ -276,7 +277,7 @@ function Public.toggle_window(player)
flow4 = flow3.add({
name = 'abandon_proposal',
type = 'button',
caption = 'Abandon Proposal',
caption = {'pirates.gui_runs_proposals_abandon_proposal'},
})
flow4.style.minimal_width = 150
flow4.style.font = 'default-bold'
@ -298,14 +299,14 @@ function Public.toggle_window(player)
flow5 = flow4.add({
type = 'label',
caption = 'Run name',
caption = {'pirates.gui_runs_proposal_maker_run_name'},
})
flow5.style.font = 'heading-3'
flow5 = flow4.add({
name = 'namefield',
type = 'textfield',
caption = 'Name',
caption = {'pirates.gui_runs_proposal_maker_run_name_2'},
text = '',
})
flow5.style.width = 150
@ -321,7 +322,7 @@ function Public.toggle_window(player)
flow5.style.width = 200
flow5.style.margin = 0
flow_add_proposal_slider(flow5, 'capacity', 'Capacity', #CoreData.capacity_options, 5, {'pirates.capacity_tooltip'})
flow_add_proposal_slider(flow5, 'capacity', {'pirates.gui_runs_proposal_maker_capacity'}, #CoreData.capacity_options, 5, {'pirates.capacity_tooltip'})
-- flow_add_proposal_slider(flow5, 'difficulty', 'Difficulty', #CoreData.difficulty_options, 2, {'pirates.difficulty_tooltip'})
-- flow_add_proposal_switch(flow5, 'mode', 'Mode', 'left', {'pirates.mode_tooltip'})
@ -336,7 +337,7 @@ function Public.toggle_window(player)
flow5 = flow4.add({
name = 'proposal_disabled_low_crew_caps',
type = 'label',
caption = 'This capacity setting isn\'t available at the moment.',
caption = {'pirates.gui_runs_proposal_maker_capacity_disabled'},
})
flow5.style.single_line = false
flow5.style.maximal_width = 200
@ -344,7 +345,7 @@ function Public.toggle_window(player)
flow5 = flow4.add({
name = 'propose_crew',
type = 'button',
caption = 'Propose',
caption = {'pirates.gui_runs_proposal_maker_propose'},
})
flow5.style.minimal_width = 75
flow5.style.font = 'default-bold'
@ -362,35 +363,35 @@ function Public.toggle_window(player)
flow4 = flow3.add({
name = 'proposal_insufficient_endorsers',
type = 'label',
caption = 'Gather support from more pirates.',
caption = {'pirates.gui_runs_launch_error_1'},
})
flow4.style.single_line = false
flow4 = flow3.add({
name = 'proposal_crew_count_capped',
type = 'label',
caption = 'The number of concurrent runs on the server has reached the cap set by the admins.',
caption = {'pirates.gui_runs_launch_error_2'},
})
flow4.style.single_line = false
flow4 = flow3.add({
name = 'proposal_insufficient_player_capacity',
type = 'label',
caption = "Can't launch; at least one run needs high player capacity.",
caption = {'pirates.gui_runs_launch_error_3'},
})
flow4.style.single_line = false
flow4 = flow3.add({
name = 'proposal_insufficient_sloops',
type = 'label',
caption = 'No sloops available. Join an existing run instead.',
caption = {'pirates.gui_runs_launch_error_4'},
})
flow4.style.single_line = false
flow4 = flow3.add({
name = 'launch_crew',
type = 'button',
caption = 'Launch run',
caption = {'pirates.gui_runs_launch'},
})
flow4.style.minimal_width = 150
flow4.style.font = 'default-bold'
@ -441,7 +442,7 @@ function Public.full_update(player)
flow.ongoing_runs.body.wait_to_join.visible = selected_joinable_bool and crewid and global_memory.crew_memories[crewid] and (global_memory.crew_memories[crewid].tempbanned_from_joining_data and global_memory.crew_memories[crewid].tempbanned_from_joining_data[player.index] and game.tick < global_memory.crew_memories[crewid].tempbanned_from_joining_data[player.index] + Common.ban_from_rejoining_crew_ticks) and (not (global_memory.crew_memories[crewid].crewstatus == Crew.enum.LEAVING_INITIAL_DOCK or #global_memory.crew_memories[crewid].crewplayerindices >= global_memory.crew_memories[crewid].capacity))
if flow.ongoing_runs.body.wait_to_join.visible then
flow.ongoing_runs.body.wait_to_join.caption = 'Wait to join... ' .. Math.ceil(((global_memory.crew_memories[crewid].tempbanned_from_joining_data[player.index] - (game.tick - Common.ban_from_rejoining_crew_ticks)))/60)
flow.ongoing_runs.body.wait_to_join.caption = {'pirates.gui_runs_wait_to_join', Math.ceil(((global_memory.crew_memories[crewid].tempbanned_from_joining_data[player.index] - (game.tick - Common.ban_from_rejoining_crew_ticks)))/60)}
end
if not selected_joinable_bool then flow.ongoing_runs.body.ongoing_runs_listbox.selected_index = 0 end
@ -477,7 +478,7 @@ function Public.full_update(player)
-- flow.proposals.body.proposal_maker.body.proposal_cant_do_infinity_mode.visible = (flow.proposals.body.proposal_maker.body.options.mode.mode.switch.switch_state == 'right')
-- flow.proposals.body.proposal_maker.body.proposal_disabled_low_crew_caps.visible = false
flow.proposals.body.proposal_maker.body.proposal_disabled_low_crew_caps.visible = (flow.proposals.body.proposal_maker.body.options.capacity.capacity.slider.slider_value < global_memory.minimum_capacity_slider_value)
flow.proposals.body.proposal_maker.body.proposal_disabled_low_crew_caps.visible = (flow.proposals.body.proposal_maker.body.options.capacity.capacity.slider.slider_value < global_memory.minimumCapacitySliderValue)
flow.proposals.body.proposal_maker.body.propose_crew.visible = (flow.proposals.body.proposal_maker.body.proposal_disabled_low_crew_caps.visible == false)
-- flow.proposals.body.proposal_maker.body.propose_crew.visible = (flow.proposals.body.proposal_maker.body.proposal_cant_do_infinity_mode.visible == false) and (flow.proposals.body.proposal_maker.body.proposal_disabled_low_crew_caps.visible == false)
@ -499,7 +500,7 @@ function Public.full_update(player)
elseif mem.crewplayerindices then
count = #mem.crewplayerindices
end
wrappedmemories[#wrappedmemories + 1] = {'pirates.run_displayform', mem.id, mem.name .. ', ' .. CoreData.difficulty_options[mem.difficulty_option].text .. ', [item=light-armor]' .. count .. CoreData.capacity_options[mem.capacity_option].text2 .. ', [item=rail] ' .. (mem.overworldx or 0)}
wrappedmemories[#wrappedmemories + 1] = {'pirates.run_displayform', mem.id, {'', mem.name .. ', ', CoreData.difficulty_options[mem.difficulty_option].text, ', [item=light-armor]' .. count .. CoreData.capacity_options[mem.capacity_option].text2 .. ', [item=rail] ' .. (mem.overworldx or 0)}}
-- wrappedmemories[#wrappedmemories + 1] = {'pirates.run_displayform', mem.id, mem.name, Utils.spritepath_to_richtext(CoreData.difficulty_options[mem.difficulty_option].icon), count, CoreData.capacity_options[mem.capacity_option].text2, ' [item=rail] ', mem.overworldx or 0}
end
GuiCommon.update_listbox(flow.ongoing_runs.body.ongoing_runs_listbox, wrappedmemories)
@ -523,7 +524,7 @@ function Public.full_update(player)
flow.proposals.body.proposal_maker.body.options.capacity_readoff_icon.sprite = opt.icon
end
end
if flow.proposals.body.proposal_maker.body.options.capacity.capacity.readoff_text.caption == '' then flow.proposals.body.proposal_maker.body.options.capacity.capacity.readoff_text.caption = 'No limit' end
if flow.proposals.body.proposal_maker.body.options.capacity.capacity.readoff_text.caption == '' then flow.proposals.body.proposal_maker.body.options.capacity.capacity.readoff_text.caption = {'pirates.gui_runs_proposal_maker_no_limit'} end
-- local difficulty_slider_value = flow.proposals.body.proposal_maker.body.options.difficulty.difficulty.slider.slider_value
-- for i, opt in pairs(CoreData.difficulty_options) do
@ -629,7 +630,8 @@ function Public.click(event)
global_memory.crewproposals[#global_memory.crewproposals + 1] = proposal
local message = player.name .. ' proposed the run ' .. proposal_name .. ' [capacity ' .. CoreData.capacity_options[capacity_option].text3 .. '].'
local message = {'pirates.proposal_propose', player.name, proposal_name, CoreData.capacity_options[capacity_option].text3}
-- local message = player.name .. ' proposed the run ' .. proposal_name .. ' (difficulty ' .. CoreData.difficulty_options[difficulty_option].text .. ', capacity ' .. CoreData.capacity_options[capacity_option].text3 .. ').'
Common.notify_lobby(message)
return

View File

@ -1,4 +1,7 @@
-- Adapted from mountain_fortress_v3 highscores.lua
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- == This code is mostly a fork of the file from Mountain Fortress
local Event = require 'utils.event'
local Global = require 'utils.global'
@ -12,6 +15,7 @@ local SpamProtection = require 'utils.spam_protection'
-- local Memory = require 'maps.pirates.memory'
local Utils = require 'maps.pirates.utils_local'
local CoreData = require 'maps.pirates.coredata'
local Common = require 'maps.pirates.common'
local module_name = Gui.uid_name()
-- local module_name = 'Highscore'
@ -21,8 +25,6 @@ local score_key_debug = 'pirate_ship_scores_debug'
local score_key_modded = 'pirate_ship_scores_modded'
-- == This code is mostly a fork of the file from Mountain Fortress
local Public = {}
local insert = table.insert
@ -42,19 +44,24 @@ local function sort_list(method, column_name, score_list)
local comparators = {
['ascending'] = function(a, b)
if column_name == 'completion_time' then
return (a[column_name] < b[column_name]) and not (a[column_name] == 0 and b[column_name] ~= 0)
return ((a[column_name] < b[column_name]) and not (a[column_name] == 0 and b[column_name] ~= 0)) or (a[column_name] ~= 0 and b[column_name] == 0) --put all 0s at the end
elseif column_name == 'version' then
return Common.version_greater_than(b[column_name], a[column_name])
elseif type(a[column_name]) == 'string' then
return a[column_name] > b[column_name]
else
elseif a[column_name] then
return a[column_name] < b[column_name]
end
end,
--nosort
['descending'] = function(a, b)
if column_name == 'completion_time' then
return (a[column_name] > b[column_name])
return ((b[column_name] < a[column_name]) and not (a[column_name] == 0 and b[column_name] ~= 0)) or (a[column_name] ~= 0 and b[column_name] == 0) --put all 0s at the end
elseif column_name == 'version' then
return Common.version_greater_than(a[column_name], b[column_name])
elseif type(a[column_name]) == 'string' then
return a[column_name] < b[column_name]
else
elseif a[column_name] then
return a[column_name] > b[column_name]
end
end
@ -81,7 +88,7 @@ local function get_tables_of_scores_by_type(scores)
local versions = {}
for _, score in pairs(scores) do
if score.version and score.version > 0 then
if score.version then
versions[#versions + 1] = score.version
end
if score.completion_time and score.completion_time > 0 then
@ -110,11 +117,11 @@ local function get_tables_of_scores_by_type(scores)
local latest_version = 0
for _, v in pairs(versions) do
if v > latest_version then latest_version = v end
if Common.version_greater_than(v, latest_version) then latest_version = v end
end
for _, score in pairs(scores) do
if score.version and score.version == latest_version then
if score.version and type(score.version) == type(latest_version) and score.version == latest_version then
if score.completion_time and score.completion_time > 0 then
completion_times_latestv[#completion_times_latestv + 1] = score.completion_time
end
@ -202,16 +209,16 @@ local function saved_scores_trim(scores)
local include = false
if cutoffs.completion_times_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_cutoff then include = true
elseif cutoffs.completion_times_mediump_latestv_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_mediump_latestv_cutoff and score.version == cutoffs.latest_version and score.difficulty >= 1 then include = true
elseif cutoffs.completion_times_mediump_latestv_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_mediump_latestv_cutoff and type(score.version) == type(cutoffs.latest_version) and score.version == cutoffs.latest_version and score.difficulty >= 1 then include = true
elseif cutoffs.completion_times_hard_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_hard_cutoff and score.difficulty > 1 then include = true
elseif cutoffs.completion_times_nightmare_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_nightmare_cutoff and score.difficulty > 2 then include = true
elseif cutoffs.completion_times_latestv_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_latestv_cutoff and score.version == cutoffs.latest_version then include = true
elseif cutoffs.completion_times_latestv_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_latestv_cutoff and type(score.version) == type(cutoffs.latest_version) and score.version == cutoffs.latest_version then include = true
elseif cutoffs.leagues_travelled_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_cutoff then include = true
elseif cutoffs.leagues_travelled_mediump_latestv_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_mediump_latestv_cutoff and score.version == cutoffs.latest_version and score.difficulty >= 1 then include = true
elseif cutoffs.leagues_travelled_mediump_latestv_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_mediump_latestv_cutoff and type(score.version) == type(cutoffs.latest_version) and score.version == cutoffs.latest_version and score.difficulty >= 1 then include = true
elseif cutoffs.leagues_travelled_hard_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_hard_cutoff and score.difficulty > 1 then include = true
elseif cutoffs.leagues_travelled_nightmare_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_nightmare_cutoff and score.difficulty > 2 then include = true
elseif cutoffs.leagues_travelled_latestv_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_latestv_cutoff and score.version == cutoffs.latest_version then include = true
elseif cutoffs.leagues_travelled_latestv_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_latestv_cutoff and type(score.version) == type(cutoffs.latest_version) and score.version == cutoffs.latest_version then include = true
end
if not include then delete[#delete + 1] = secs_id end
@ -307,7 +314,7 @@ function Public.overwrite_scores_specific()
-- the correct format is to put _everything_ from a dump into the third argument:
-- Server.set_data(score_dataset, score_key, )
-- return true
return nil
return true
end
function Public.write_score(crew_secs_id, name, captain_name, completion_time, leagues_travelled, version, difficulty, max_players)
@ -406,13 +413,13 @@ local function score_gui(data)
-- Score headers
local headers = {
{name = '_name', caption = 'Crew'},
{column = 'captain_name', name = '_captain_name', caption = 'Captain'},
{column = 'completion_time', name = '_completion_time', caption = 'Completion'},
{column = 'leagues_travelled', name = '_leagues_travelled', caption = 'Leagues'},
{column = 'version', name = '_version', caption = 'Version'},
{column = 'difficulty', name = '_difficulty', caption = 'Difficulty'},
{column = 'max_players', name = '_max_players', caption = 'PeakPlayers'},
{name = '_name', caption = {'pirates.highscore_heading_crew'}},
{column = 'captain_name', name = '_captain_name', caption = {'pirates.highscore_heading_captain'}, tooltip = {'pirates.highscore_heading_captain_tooltip'}},
{column = 'completion_time', name = '_completion_time', caption = {'pirates.highscore_heading_completion'}},
{column = 'leagues_travelled', name = '_leagues_travelled', caption = {'pirates.highscore_heading_leagues'}},
{column = 'version', name = '_version', caption = {'pirates.highscore_heading_version'}},
{column = 'difficulty', name = '_difficulty', caption = {'pirates.highscore_heading_difficulty'}},
{column = 'max_players', name = '_max_players', caption = {'pirates.highscore_heading_peak_players'}},
}
local sorting_pref = this.sort_by[player.index] or {}
@ -424,7 +431,7 @@ local function score_gui(data)
-- Add sorting symbol if any
if header.column and sorting_pref[1] and sorting_pref[1].column == header.column then
local symbol = sorting_symbol[sorting_pref[1].method]
cap = symbol .. cap
cap = {'', symbol, cap}
end
-- Header
@ -434,6 +441,7 @@ local function score_gui(data)
caption = cap,
name = header.name
}
if header.tooltip then label.tooltip = header.tooltip end
label.style.font = 'default-listbox'
label.style.font_color = {r = 0.98, g = 0.66, b = 0.22} -- yellow
label.style.minimal_width = columnwidth
@ -447,6 +455,7 @@ local function score_gui(data)
for i = #sorting_pref, 1, -1 do
local sort = sorting_pref[i]
if sort then
-- log(_inspect(score_list))
score_list = sort_list(sort.method, sort.column, score_list)
end
end
@ -487,8 +496,8 @@ local function score_gui(data)
-- displayforms:
local n = entry.completion_time > 0 and Utils.time_mediumform(entry.completion_time or 0) or 'N/A'
local l = entry.leagues_travelled > 0 and entry.leagues_travelled or '?'
local v = entry.version > 0 and entry.version or '?'
local d = entry.difficulty > 0 and CoreData.get_difficulty_name_from_value(entry.difficulty) or '?'
local v = entry.version and entry.version or '?'
local d = entry.difficulty > 0 and CoreData.difficulty_options[CoreData.get_difficulty_option_from_value(entry.difficulty)].text or '?'
local c = entry.max_players > 0 and entry.max_players or '?'
local line = {
{caption = entry.name, color = special_color},
@ -496,7 +505,7 @@ local function score_gui(data)
{caption = tostring(n)},
{caption = tostring(l)},
{caption = tostring(v)},
{caption = tostring(d)},
{caption = d},
{caption = tostring(c)},
}
local default_color = {r = 0.9, g = 0.9, b = 0.9}

View File

@ -1,3 +1,4 @@
-- by mewmew
-- modified by Gerkiz

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Math = require 'maps.pirates.math'
-- local Memory = require 'maps.pirates.memory'
@ -212,16 +214,16 @@ function Public.wooden_chest_loot()
local num = 1
return Public.chest_loot(num,
Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress())) --enforce 0 to 1
)
Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress())
)
end
function Public.iron_chest_loot()
local num = 2
local loot = Public.chest_loot(num,
Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (5/100 + Common.game_completion_progress()))) --enforce 0 to 1
) --reward higher difficulties with better loot
Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * (5/100 + Common.game_completion_progress()))
) --reward higher difficulties with better loot
loot[#loot + 1] = {name = 'coin', count = Math.random(500,1500)}
return loot
@ -231,12 +233,26 @@ function Public.covered_wooden_chest_loot()
local num = 2
local loot = Public.chest_loot(num,
Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (10/100 + Common.game_completion_progress()))) --enforce 0 to 1
) --reward higher difficulties with better loot
Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * (18/100 + Common.game_completion_progress()))
) --reward higher difficulties with better loot
return loot
end
function Public.covered_wooden_chest_loot_1()
return {
{name = 'iron-plate', count = 650},
{name = 'copper-plate', count = 200}
}
end
function Public.covered_wooden_chest_loot_2()
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.chest_loot_data_raw), 2,
Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * (10/100 + Common.game_completion_progress())))
end
function Public.stone_furnace_loot()
return {
{name = 'coal', count = 50},
@ -249,7 +265,7 @@ function Public.storage_tank_fluid_loot(force_type)
ret = {name = 'crude-oil', amount = Math.random(3000, 12500)}
elseif force_type == 'petroleum-gas' then
ret = {name = 'petroleum-gas', amount = Math.random(1500, 7500)}
elseif rng < 6 then
elseif rng <= 6 then
ret = {name = 'crude-oil', amount = Math.random(1500, 4500)}
elseif rng == 7 then
ret = {name = 'light-oil', amount = Math.random(1500, 3500)}
@ -271,7 +287,7 @@ end
function Public.roboport_bots_loot()
return {
{name = 'logistic-robot', count = 5},
{name = 'logistic-robot', count = 8},
}
-- construction robots
end
@ -307,7 +323,7 @@ function Public.maze_camp_loot()
if Math.random(10) <= 7 then
return {Public.random_plates()}
else
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.chest_loot_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (15/100 + Common.game_completion_progress()))))
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.chest_loot_data_raw), 1, Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * (15/100 + Common.game_completion_progress())))
end
end
@ -323,7 +339,7 @@ Public.maze_lab_loot_data_raw = {
}
function Public.maze_lab_loot()
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_lab_loot_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (Common.game_completion_progress()))))
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_lab_loot_data_raw), 1, Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * (Common.game_completion_progress())))
end
Public.maze_treasure_data_raw = {
@ -393,7 +409,7 @@ function Public.maze_treasure_loot()
if Math.random(5) == 1 then
return {Public.random_plates(8)}
else
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_treasure_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (Common.game_completion_progress()))))
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_treasure_data_raw), 1, Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * (Common.game_completion_progress())))
end
end
@ -442,7 +458,7 @@ Public.dredger_loot_raw = {
}
function Public.dredger_loot()
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.dredger_loot_raw), 1, Math.max(0,Math.min(1, Common.game_completion_progress())))
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.dredger_loot_raw), 1, Math.clamp(0, 1, Common.game_completion_progress()))
end
return Public

View File

@ -1,3 +1,4 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
--[[
Pirate Ship is maintained by thesixthroc and hosted by Comfy.
@ -11,9 +12,17 @@ The scenario is quite complex, but there are ways to get started, even if you do
Go to pirates/surfaces/islands/first and edit stuff there to see the effect it has on the first island
Ask thesixthroc for access to the ToDo list on Github Projects, to see what needs doing
Make sure to use debug=true in control.lua
]]
--[[personal note for thesixthroc in XX years: my design notes are all in Obsidian (edit: mostly moved to Github Projects)]]
--[[
personal note for thesixthroc looking at this in XX years: my design notes are all in Obsidian (edit: mostly moved to Github Projects)
]]
--[[
Convention for Factorio blueprints in this folder: Use Snap to grid -> Relative, Offset of zeroes.
We record tiles and entities separately. For tiles, we use the factorio dev approved 'concrete trick', painting each tile type separately as concrete. The concrete BP will typically need an offset, since it doesn't remember the center of the entities BP — we configure this offset in the Lua rather than the BP itself, since it's easier to edit that way.
]]
-- require 'modules.biters_yield_coins'
@ -30,8 +39,8 @@ local Autostash = require 'modules.autostash'
require 'modules.inserter_drops_pickup'
local TickFunctions = require 'maps.pirates.tick_functions'
local ClassTickFunctions = require 'maps.pirates.tick_functions_classes'
local PiratesApiOnTick = require 'maps.pirates.api_on_tick'
local ClassPiratesApiOnTick = require 'maps.pirates.roles.tick_functions'
require 'maps.pirates.commands'
require 'maps.pirates.math'
@ -45,9 +54,10 @@ local Crew = require 'maps.pirates.crew'
local Roles = require 'maps.pirates.roles.roles'
local Structures = require 'maps.pirates.structures.structures'
local Surfaces = require 'maps.pirates.surfaces.surfaces'
local Interface = require 'maps.pirates.interface'
local PiratesApiEvents = require 'maps.pirates.api_events'
require 'maps.pirates.structures.boats.boats'
local Progression = require 'maps.pirates.progression'
local QuestStructures = require 'maps.pirates.structures.quest_structures.quest_structures'
local Ai = require 'maps.pirates.ai'
require 'maps.pirates.ores'
require 'maps.pirates.quest'
@ -97,13 +107,13 @@ local function on_init()
Common.init_game_settings(Balance.technology_price_multiplier)
global_memory.active_crews_cap = Common.active_crews_cap
global_memory.minimum_capacity_slider_value = Common.minimum_capacity_slider_value
global_memory.active_crews_cap = Common.activeCrewsCap
global_memory.minimumCapacitySliderValue = Common.minimumCapacitySliderValue
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
@ -120,10 +130,6 @@ local function on_init()
-- Delay.global_add(Delay.global_enum.PLACE_LOBBY_JETTY_AND_BOATS)
Task.set_timeout_in_ticks(2, jetty_delayed, {})
if _DEBUG then
game.print('Debug mode on. Use /go to get started (sometimes crashes)')
end
end
local event = require 'utils.event'
@ -138,189 +144,133 @@ local function crew_tick()
local destination = Common.current_destination()
local tick = game.tick
TickFunctions.boat_movement_tick(5) --arguments are tick intervals
-- TickFunctions.parrot_tick(5)
if tick % 10 == 0 then
TickFunctions.prevent_disembark(10)
TickFunctions.prevent_unbarreling_off_ship(10)
end
if memory.age and memory.overworldx and memory.overworldx > 0 then
memory.age = memory.age + 5
end
if memory.real_age then
memory.real_age = memory.real_age + 5
end
if tick % 60 == 0 then
TickFunctions.captain_warn_afk(60)
end
if tick % Common.loading_interval == 0 then
TickFunctions.loading_update(Common.loading_interval)
end
PiratesApiOnTick.boat_movement_tick(5) --arguments are tick intervals
-- PiratesApiOnTick.parrot_tick(5)
if tick % 5 == 0 then
TickFunctions.quest_progress_tick(5)
end
if tick % 5 == 0 then
TickFunctions.strobe_player_colors(5)
end
PiratesApiOnTick.quest_progress_tick(5)
PiratesApiOnTick.strobe_player_colors(5)
if tick % 10 == 0 then
TickFunctions.shop_ratelimit_tick(10)
end
PiratesApiOnTick.prevent_disembark(10)
PiratesApiOnTick.prevent_unbarreling_off_ship(10)
PiratesApiOnTick.shop_ratelimit_tick(10)
PiratesApiOnTick.pick_up_tick(10)
QuestStructures.tick_quest_structure_entry_price_check(10)
PiratesApiOnTick.update_boat_stored_resources(10)
if tick % 30 == 0 then
TickFunctions.silo_update(30)
end
if tick % 30 == 0 then
PiratesApiOnTick.silo_update(30)
PiratesApiOnTick.buried_treasure_check(30)
ClassPiratesApiOnTick.update_character_properties(30)
ClassPiratesApiOnTick.class_update_auxiliary_data(30)
ClassPiratesApiOnTick.class_renderings(30)
if tick % 60 == 0 then
TickFunctions.ship_deplete_fuel(60)
end
if tick % 60 == 0 then
PiratesApiOnTick.captain_warn_afk(60)
PiratesApiOnTick.ship_deplete_fuel(60)
if memory.boat and memory.boat.state == Structures.Boats.enum_state.ATSEA_SAILING then
PiratesApiOnTick.crowsnest_natural_move(60)
end
PiratesApiOnTick.slower_boat_tick(60)
PiratesApiOnTick.raft_raids(60)
PiratesApiOnTick.place_cached_structures(60)
if tick % 10 == 0 then
TickFunctions.pick_up_tick(10)
end
if tick % 60 == 0 then
if memory.boat and memory.boat.state == Structures.Boats.enum_state.ATSEA_SAILING then
TickFunctions.crowsnest_natural_move(120)
end
end
if destination.dynamic_data.timer then
destination.dynamic_data.timer = destination.dynamic_data.timer + 1
end
if tick % 60 == 15 or tick % 60 == 45 then
if memory.boat and memory.boat.state == Structures.Boats.enum_state.ATSEA_SAILING then
TickFunctions.overworld_check_collisions(120)
end
end
if tick % 60 == 30 then
if memory.boat and memory.boat.state == Structures.Boats.enum_state.ATSEA_SAILING then
TickFunctions.crowsnest_steer(120)
end
end
if tick % 60 == 0 then
TickFunctions.slower_boat_tick(60)
end
if tick % 10 == 0 then
TickFunctions.update_boat_stored_resources(10)
end
if tick % 10 == 0 then
TickFunctions.covered_requirement_check(10)
end
if tick % 30 == 0 then
TickFunctions.buried_treasure_check(30)
end
if tick % 60 == 0 then
TickFunctions.raft_raids(60)
end
if tick % 60 == 0 then
TickFunctions.place_cached_structures(60)
end
if tick % 240 == 0 then
TickFunctions.check_all_spawners_dead(240)
end
if tick % 60 == 0 then
if destination.dynamic_data.timer then
destination.dynamic_data.timer = destination.dynamic_data.timer + 1
end
if memory.captain_acceptance_timer then
memory.captain_acceptance_timer = memory.captain_acceptance_timer - 1
if memory.captain_acceptance_timer == 0 then
Roles.assign_captain_based_on_priorities()
end
end
if memory.captain_accrued_time_data and memory.playerindex_captain and memory.overworldx and memory.overworldx > 0 and memory.overworldx < CoreData.victory_x then --only count time in the 'main game'
local player = game.players[memory.playerindex_captain]
if player and player.name then
if (not memory.captain_accrued_time_data[player.name]) then memory.captain_accrued_time_data[player.name] = 0 end
memory.captain_accrued_time_data[player.name] = memory.captain_accrued_time_data[player.name] + 1
end
end
if destination.dynamic_data.time_remaining and destination.dynamic_data.time_remaining > 0 then
destination.dynamic_data.time_remaining = destination.dynamic_data.time_remaining - 1
if destination.dynamic_data.time_remaining == 0 then
if memory.boat and memory.boat.surface_name then
local surface_name_decoded = Surfaces.SurfacesCommon.decode_surface_name(memory.boat.surface_name)
local type = surface_name_decoded.type
if type == Surfaces.enum.ISLAND then
Progression.retreat_from_island(false)
elseif type == Surfaces.enum.DOCK then
Progression.undock_from_dock(false)
if memory.captain_acceptance_timer then
memory.captain_acceptance_timer = memory.captain_acceptance_timer - 1
if memory.captain_acceptance_timer == 0 then
Roles.assign_captain_based_on_priorities()
end
end
if memory.captain_accrued_time_data and memory.playerindex_captain and memory.overworldx and memory.overworldx > 0 and memory.overworldx < CoreData.victory_x then --only count time in the 'main game'
local player = game.players[memory.playerindex_captain]
if player and player.name then
if (not memory.captain_accrued_time_data[player.name]) then memory.captain_accrued_time_data[player.name] = 0 end
memory.captain_accrued_time_data[player.name] = memory.captain_accrued_time_data[player.name] + 1
end
end
if destination.dynamic_data.time_remaining and destination.dynamic_data.time_remaining > 0 then
destination.dynamic_data.time_remaining = destination.dynamic_data.time_remaining - 1
if destination.dynamic_data.time_remaining == 0 then
if memory.boat and memory.boat.surface_name then
local surface_name_decoded = Surfaces.SurfacesCommon.decode_surface_name(memory.boat.surface_name)
local type = surface_name_decoded.type
if type == Surfaces.enum.ISLAND then
Progression.retreat_from_island(false)
elseif type == Surfaces.enum.DOCK then
Progression.undock_from_dock(false)
end
end
end
end
if tick % 120 == 0 then
Ai.Tick_actions(120)
if tick % 240 == 0 then
PiratesApiOnTick.check_all_spawners_dead(240)
if memory.max_players_recorded then
local count_now = #Common.crew_get_crew_members()
if count_now and count_now > memory.max_players_recorded then
memory.max_players_recorded = count_now
end
end
PiratesApiOnTick.Kraken_Destroyed_Backup_check(240)
PiratesApiOnTick.LOS_tick(240)
end
end
if tick % 300 == 0 then
PiratesApiOnTick.periodic_free_resources(300)
PiratesApiOnTick.update_recentcrewmember_list(300)
if tick % 1800 == 0 then
PiratesApiOnTick.transfer_pollution(1800)
if tick % 3600 == 0 then
PiratesApiOnTick.prune_offline_characters_list(3600)
end
end
end
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
end
if tick % 240 == 0 then
if memory.max_players_recorded then
local count_now = #Common.crew_get_crew_members()
if count_now and count_now > memory.max_players_recorded then
memory.max_players_recorded = count_now
end
if tick % 60 == 15 or tick % 60 == 45 then
if memory.boat and memory.boat.state == Structures.Boats.enum_state.ATSEA_SAILING then
PiratesApiOnTick.overworld_check_collisions(120)
end
end
if tick % 240 == 0 then
TickFunctions.Kraken_Destroyed_Backup_check(240)
if tick % 60 == 30 then
if memory.boat and memory.boat.state == Structures.Boats.enum_state.ATSEA_SAILING then
PiratesApiOnTick.crowsnest_steer(120)
end
end
if tick % 300 == 0 then
TickFunctions.periodic_free_resources(300)
if tick % Common.loading_interval == 0 then
PiratesApiOnTick.loading_update(Common.loading_interval)
end
if tick % 30 == 0 then
ClassTickFunctions.update_character_properties(30)
end
if tick % 30 == 0 then
ClassTickFunctions.class_renderings(30)
end
if tick % 120 == 0 then
Ai.Tick_actions(120)
end
if tick % 240 == 0 then
TickFunctions.LOS_tick(240)
end
if tick % 420 == 0 then
ClassTickFunctions.class_rewards_tick(420)
end
if tick % 300 == 0 then
TickFunctions.update_recentcrewmember_list(300)
end
if tick % 1800 == 0 then
TickFunctions.transfer_pollution(1800)
end
if tick % 3600 == 0 then
TickFunctions.prune_offline_characters_list(3600)
end
-- if tick % (60*60*60) == 0 then
-- Parrot.parrot_say_tip()
-- end
if memory.crew_disband_tick then
if memory.crew_disband_tick < tick then
memory.crew_disband_tick = nil
@ -336,7 +286,7 @@ local function global_tick()
local tick = game.tick
if tick % 60 == 0 then
TickFunctions.update_players_second()
PiratesApiOnTick.update_players_second()
end
if tick % 30 == 0 then
@ -354,7 +304,7 @@ local function global_tick()
crew_tick()
end
TickFunctions.update_player_guis(5)
PiratesApiOnTick.update_player_guis(5)
end
event.on_nth_tick(5, global_tick)
@ -364,8 +314,8 @@ local function instatick()
local global_memory = Memory.get_global_memory()
for _, id in pairs(global_memory.crew_active_ids) do
Memory.set_working_id(id)
TickFunctions.minimap_jam(1)
TickFunctions.silo_insta_update()
PiratesApiOnTick.minimap_jam(1)
PiratesApiOnTick.silo_insta_update()
end
end
@ -376,7 +326,7 @@ event.on_nth_tick(1, instatick)
----- FOR BUGFIXING HARD CRASHES (segfaults) ------
-- often, segfaults are due to an error during chunk generation (as of 1.1.0 or so, anyway.)
-- to help debug, comment this out, and instead use the command /chnk to generate some chunks manually
event.add(defines.events.on_chunk_generated, Interface.event_on_chunk_generated)
event.add(defines.events.on_chunk_generated, PiratesApiEvents.event_on_chunk_generated)
----- FOR DESYNC BUGFIXING -----
local gMeta = getmetatable(_ENV)

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Global = require 'utils.global'
-- local CoreData = require 'maps.pirates.coredata'
@ -35,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

View File

@ -1,6 +1,7 @@
local Public = {}
-- no longer using the below code
Public.encoding = [[!#$%&'()*+'-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ/^_`abcdefghijklmnopqrstuvwxyz{}|~]]
Public.encoding_length = 91
Public.enc = {}

View File

@ -1,7 +1,9 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Balance = require 'maps.pirates.balance'
-- local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
local Raffle = require 'maps.pirates.raffle'
local CoreData = require 'maps.pirates.coredata'
local _inspect = require 'utils.inspect'.inspect
local Common = require 'maps.pirates.common'
@ -38,7 +40,7 @@ function Public.try_ore_spawn(surface, realp, source_name, density_bonus)
if Utils.length(choices_to_prioitise) > 0 then
choice = choices_to_prioitise[Math.random(Utils.length(choices_to_prioitise))]
else
choice = Math.raffle2(choices_possible)
choice = Raffle.raffle2(choices_possible)
end
local placed

View File

@ -1,3 +1,4 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
@ -228,33 +229,33 @@ function Public.generate_overworld_destination(p)
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*120),
}
local base_cost_2 = {
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*180),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*18),
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*200),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
-- the below got this response from a new player: "This feels... underwhelming."
-- ['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*120),
-- ['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*18),
}
local base_cost_2b = {
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*180),
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*200),
['flying-robot-frame'] = 3,
}
local base_cost_3 = {
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*140),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*18),
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*160),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
['launch_rocket'] = true,
}
local base_cost_4 = {
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*100),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*18),
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*140),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
['flying-robot-frame'] = Math.ceil(((macro_p.x-18)^(2/3))*15),
['launch_rocket'] = true,
}
local base_cost_5 = {
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*100),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*18),
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*140),
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
['flying-robot-frame'] = Math.ceil(((macro_p.x-18)^(2/3))*10),
-- ['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*100),
-- ['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*18),
-- ['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
-- ['flying-robot-frame'] = Math.ceil(((macro_p.x-18)^(2/3))*10),
}
-- if macro_p.x == 0 then
@ -268,7 +269,7 @@ function Public.generate_overworld_destination(p)
-- end
-- base_cost_to_undock = nil
-- elseif macro_p.x <= 6 then
if macro_p.x <= 6 then
if macro_p.x <= Common.first_cost_to_leave_macrox - 1 then
-- base_cost_to_undock = {['electronic-circuit'] = 5}
base_cost_to_undock = nil
elseif macro_p.x <= 9 then
@ -423,14 +424,14 @@ function Public.generate_overworld_destination(p)
local x = Crowsnest.platformrightmostedge + dest.overworld_position.x
local y = dest.overworld_position.y
if dest.static_params.upgrade_for_sale then
local display_form = Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale]
local display_form = {'', Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale], ':'}
if not dest.dynamic_data.crowsnest_renderings then
dest.dynamic_data.crowsnest_renderings = {}
end
dest.dynamic_data.crowsnest_renderings.base_text_rendering = rendering.draw_text{
text = display_form .. ':',
text = display_form,
surface = surface,
target = {x = x + 5.5, y = y + 2.5},
color = CoreData.colors.renderingtext_green,
@ -538,7 +539,7 @@ function Public.ensure_lane_generated_up_to(lane_yvalue, x)
for _, dest in pairs(memory.destinations) do
if dest.static_params.upgrade_for_sale and dest.dynamic_data.crowsnest_renderings then
if rendering.is_valid(dest.dynamic_data.crowsnest_renderings.base_text_rendering) then
rendering.set_text(dest.dynamic_data.crowsnest_renderings.base_text_rendering, Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale] .. ':')
rendering.set_text(dest.dynamic_data.crowsnest_renderings.base_text_rendering, {'', Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale], ':'})
end
for rendering_name, r in pairs(dest.dynamic_data.crowsnest_renderings) do
if type(r) == 'table' and r.text_rendering and rendering.is_valid(r.text_rendering) then
@ -647,8 +648,7 @@ function Public.try_overworld_move_v2(vector) --islands stay, crowsnest moves
if memory.victory_continue_message then
memory.victory_continue_message = false
local message = 'The run now continues on \'Freeplay\'.'
Common.notify_force(memory.force, message, CoreData.colors.notify_victory)
Common.notify_force(memory.force, {'pirates.crew_continue_on_freeplay'}, CoreData.colors.notify_victory)
end
if vector.x > 0 then
@ -682,9 +682,10 @@ function Public.try_overworld_move_v2(vector) --islands stay, crowsnest moves
-- other freebies:
for i=1,vector.x do
Common.give_items_to_crew(Balance.periodic_free_resources_per_x())
Balance.apply_crew_buffs_per_x(memory.force)
end
Balance.apply_crew_buffs_per_league(memory.force, vector.x)
-- add some evo: (this will get reset upon arriving at a destination anyway, so this is just relevant for sea monsters and the like:)
local extra_evo = Balance.base_evolution_leagues(memory.overworldx) - Balance.base_evolution_leagues(memory.overworldx - vector.x)
Common.increment_evo(extra_evo)
@ -703,7 +704,7 @@ function Public.try_overworld_move_v2(vector) --islands stay, crowsnest moves
modal_captain = name
end
end
Highscore.write_score(memory.secs_id, memory.name, modal_captain, memory.completion_time or 0, memory.overworldx, CoreData.version_float, memory.difficulty, memory.max_players_recorded or 0)
Highscore.write_score(memory.secs_id, memory.name, modal_captain, memory.completion_time or 0, memory.overworldx, CoreData.version_string, memory.difficulty, memory.max_players_recorded or 0)
end
return true

View File

@ -1,12 +1,14 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Math = require 'maps.pirates.math'
local Memory = require 'maps.pirates.memory'
-- local Memory = require 'maps.pirates.memory'
local _inspect = require 'utils.inspect'.inspect
-- local Token = require 'utils.token'
-- local CoreData = require 'maps.pirates.coredata'
-- local Task = require 'utils.task'
-- local Balance = require 'maps.pirates.balance'
local Common = require 'maps.pirates.common'
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
local Public = {}
@ -53,35 +55,6 @@ Public.framecounts = {
-- "If X marks the spot - use inserters to dig!",
-- }
function Public.parrot_0()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'We can wait here for as long as we like.')
end
function Public.parrot_80()
local memory = Memory.get_crew_memory()
-- Common.parrot_speak(memory.force, 'Let\'s build out the ship?')
Common.parrot_speak(memory.force, 'Did you know that biters deal more damage at night?')
end
function Public.parrot_boats_warning()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, '200 leagues? I think we\'re being chased...')
end
function Public.parrot_kraken_warning()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, '400 leagues coming up? What are those pink things I spy...')
end
function Public.parrot_radioactive_tip_1()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'We\'ll need uranium-235 to push away from this island...')
end
function Public.parrot_radioactive_tip_2()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'The biters don\'t care if we pollute here, but they evolve fast.')
end
function Public.parrot_maze_tip_1()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'Something seems wrong with our minimap.')
end
-- function Public.parrot_800_tip()
-- local memory = Memory.get_crew_memory()
-- Common.parrot_speak(memory.force, 'The resources needed to leave will get a bit harder now...')

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
@ -196,6 +198,7 @@ local place_dock_jetty_and_boats = Token.register(
function Public.progress_to_destination(destination_index)
local memory = Memory.get_crew_memory()
if memory.game_lost then return end
@ -214,10 +217,9 @@ function Public.progress_to_destination(destination_index)
local initial_boatspeed, starting_boatposition
if type == Surfaces.enum.ISLAND then --moved from overworld generation, so that it updates properly
local covered1_requirement = Balance.covered1_entry_price()
destination_data.dynamic_data.covered1_requirement = covered1_requirement
end
-- if type == Surfaces.enum.ISLAND then --moved from overworld generation, so that it updates properly
-- Public.choose_quest_structures(destination_data)
-- end
if type == Surfaces.enum.DOCK then
local BoatData = Boats.get_scope(boat).Data
@ -448,7 +450,7 @@ function Public.try_retreat_from_island(player, manual) -- Assumes the cost can
if Common.query_can_pay_cost_to_leave() then
if destination.dynamic_data.timeratlandingtime and destination.dynamic_data.timer < destination.dynamic_data.timeratlandingtime + 10 then
if player and Common.validate_player(player) then
Common.notify_player_error(player, 'Undock error: Can\'t undock in the first 10 seconds.')
Common.notify_player_error(player, {'pirates.error_undock_too_early'})
end
else
local cost = destination.static_params.base_cost_to_undock
@ -462,7 +464,7 @@ function Public.try_retreat_from_island(player, manual) -- Assumes the cost can
end
else
if player and Common.validate_player(player) then
Common.notify_force_error(player.force, 'Undock error: Not enough resources stored in the captain\'s cabin.')
Common.notify_force_error(player.force, {'pirates.error_undock_insufficient_resources'})
end
end
end
@ -481,9 +483,9 @@ function Public.retreat_from_island(manual)
local force = memory.force
if not (force and force.valid) then return end
if manual then
Common.notify_force(force,'[font=heading-1]Ship undocked[/font] by captain.')
Common.notify_force(force, {'pirates.ship_undocked_1'})
else
Common.notify_force(force,'[font=heading-1]Ship auto-undocked[/font]. Return to ship.')
Common.notify_force(force, {'pirates.ship_undocked_2'})
end
Surfaces.destination_on_departure(Common.current_destination())
@ -512,13 +514,50 @@ function Public.undock_from_dock(manual)
local force = memory.force
if not (force and force.valid) then return end
if manual then
Common.notify_force(force,'[font=heading-1]Ship undocked[/font].')
Common.notify_force(force, {'pirates.ship_undocked_1'})
else
Common.notify_force(force,'[font=heading-1]Ship auto-undocked[/font].')
Common.notify_force(force, {'pirates.ship_undocked_3'})
end
end
function Public.at_sea_begin_to_set_sail()
local memory = Memory.get_crew_memory()
local boat = memory.boat
boat.state = Boats.enum_state.ATSEA_SAILING
script.raise_event(CustomEvents.enum['update_crew_fuel_gui'], {})
Crew.summon_crew()
local force = memory.force
if not (force and force.valid) then return end
Common.notify_force(force, {'pirates.ship_set_off_to_next_island'})
end
local parrot_set_sail_advice =
Token.register(
function(data)
local crew_id = data.crew_id
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
if memory.boat and memory.boat.state and memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL then
Common.parrot_speak(memory.force, {'pirates.parrot_set_sail_advice'})
end
end
)
function Public.go_from_currentdestination_to_sea()
local memory = Memory.get_crew_memory()
@ -538,23 +577,25 @@ function Public.go_from_currentdestination_to_sea()
if memory.overworldx == 0 and memory.boat then
local difficulty_name = CoreData.get_difficulty_name_from_value(memory.difficulty)
if difficulty_name == CoreData.difficulty_options[#CoreData.difficulty_options].text then
local difficulty_name = CoreData.get_difficulty_option_informal_name_from_value(memory.difficulty)
if difficulty_name == 'nightmare' then
Boats.upgrade_chests(boat, 'steel-chest')
Hold.upgrade_chests(1, 'steel-chest')
Crowsnest.upgrade_chests('steel-chest')
Common.parrot_speak(memory.force, 'Steel chests for steel players! Squawk!')
elseif difficulty_name ~= CoreData.difficulty_options[1].text then
Common.parrot_speak(memory.force, {'pirates.parrot_hard_praise'})
elseif difficulty_name ~= 'easy' then
Boats.upgrade_chests(boat, 'iron-chest')
Hold.upgrade_chests(1, 'iron-chest')
Crowsnest.upgrade_chests('iron-chest')
Common.parrot_speak(memory.force, 'Iron chests for iron players! Squawk!')
Common.parrot_speak(memory.force, {'pirates.parrot_normal_praise'})
Task.set_timeout_in_ticks(60 * 10, parrot_set_sail_advice, {crew_id = memory.id})
end
end
memory.boat.state = Boats.enum_state.ATSEA_SAILING
memory.boat.state = Boats.enum_state.ATSEA_WAITING_TO_SAIL
memory.boat.speed = 0
memory.boat.position = new_boatposition
memory.boat.surface_name = seaname

View File

@ -1,3 +1,4 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
@ -5,6 +6,7 @@ local Balance = require 'maps.pirates.balance'
local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
local Math = require 'maps.pirates.math'
local Raffle = require 'maps.pirates.raffle'
-- local Loot = require 'maps.pirates.loot'
local CoreData = require 'maps.pirates.coredata'
local _inspect = require 'utils.inspect'.inspect
@ -67,8 +69,6 @@ function Public.initialise_random_quest()
destination.dynamic_data.quest_complete = false
if destination.destination_index == 2 then return end
local rng = Math.random(100)
if rng <= 10 then
Public.initialise_nodamage_quest()
@ -149,11 +149,13 @@ function Public.initialise_resourceflow_quest()
destination.dynamic_data.quest_progress = 0
local generated_flow_quest = Public.generate_flow_quest()
if not generated_flow_quest then return false end
destination.dynamic_data.quest_params = {item = generated_flow_quest.item}
local progressneeded_before_rounding = generated_flow_quest.base_rate * Balance.resource_quest_multiplier()
destination.dynamic_data.quest_progressneeded = Math.ceil(progressneeded_before_rounding/10)*10
destination.dynamic_data.quest_progressneeded = Math.ceil(progressneeded_before_rounding/10) * 10
return true
end
@ -170,6 +172,8 @@ function Public.initialise_resourcecount_quest()
destination.dynamic_data.quest_progress = 0
local generated_production_quest = Public.generate_resourcecount_quest()
if not generated_production_quest then return false end
destination.dynamic_data.quest_params = {item = generated_production_quest.item}
local force = memory.force
@ -207,10 +211,10 @@ function Public.initialise_worms_quest()
if Common.difficulty_scale() < 1 then needed = Math.max(1, needed - 3) end
if Common.difficulty_scale() > 1 then needed = Math.max(1, needed + 2) end
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty_scale())
if difficulty_name == CoreData.difficulty_options[1].text then
local difficulty_name = CoreData.get_difficulty_option_informal_name_from_value(Common.difficulty_scale())
if difficulty_name == 'easy' then
needed = Math.max(1, needed - 3)
elseif difficulty_name ~= CoreData.difficulty_options[2].text then
elseif difficulty_name ~= 'normal' then
needed = Math.max(1, needed + 2)
end
@ -237,7 +241,7 @@ function Public.try_resolve_quest()
local force = memory.force
if not (force and force.valid) then return end
Common.notify_force_light(force,'Granted: ' .. destination.dynamic_data.quest_reward.display_amount .. ' ' .. destination.dynamic_data.quest_reward.chat_name)
Common.notify_force_light(force, {'pirates.granted_1', {'pirates.granted_quest_complete'}, destination.dynamic_data.quest_reward.display_amount .. destination.dynamic_data.quest_reward.chat_name})
local name = destination.dynamic_data.quest_reward.name
local count = destination.dynamic_data.quest_reward.count
@ -266,7 +270,7 @@ function Public.try_resolve_quest()
local inventory2 = chest2.get_inventory(defines.inventory.chest)
local inserted2 = inventory2.insert{name = name, count = count - inserted}
if (inserted + inserted2) < count then
Common.notify_force(force,'Sadly, there wasn\'t space in the cabin for all of your reward.')
Common.notify_force(force, {'pirates.error_cabin_full'})
end
end
end
@ -331,7 +335,7 @@ function Public.generate_flow_quest()
end
end
return Math.raffle(v, w)
return Raffle.raffle(v, w)
end
@ -398,7 +402,7 @@ function Public.generate_resourcecount_quest()
end
end
return Math.raffle(v, w)
return Raffle.raffle(v, w)
end

142
maps/pirates/raffle.lua Normal file
View File

@ -0,0 +1,142 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Math = require 'maps.pirates.math'
local Public = {}
function Public.raffle(values, weights) --arguments of the form {[a] = A, [b] = B, ...} and {[a] = a_weight, [b] = b_weight, ...} or just {a,b,c,...} and {1,2,3...}
local total_weight = 0
for k,w in pairs(weights) do
assert(values[k])
if w > 0 then
total_weight = total_weight + w
end
-- negative weights treated as zero
end
if (not (total_weight > 0)) then return nil end
local cumulative_probability = 0
local rng = Math.random()
for k,v in pairs(values) do
assert(weights[k])
cumulative_probability = cumulative_probability + (weights[k] / total_weight)
if rng <= cumulative_probability then
return v
end
end
end
function Public.raffle2(table) --arguments of the form {v1 = w1, v2 = w2, ...}
local total_weight = 0
for k,w in pairs(table) do
if w > 0 then
total_weight = total_weight + w
end
-- negative weights treated as zero
end
if (not (total_weight > 0)) then return nil end
local cumulative_probability = 0
local rng = Math.random()
for k,v in pairs(table) do
cumulative_probability = cumulative_probability + v/total_weight
if rng <= cumulative_probability then
return k
end
end
end
--==thesixthroc's Lambda Raffles
-- This file provides a one-parameter family of raffles called 'Lambda raffles'. When you want to roll the raffle, you also provide a parameter 'lambda', and the raffle weights vary with lambda in a specified way. For example, the parameter could be the game completion progress, and the raffle could produce certain items only in the late game.
function Public.LambdaRaffle(data, lambda, extraConditionParameter)
-- example_argument = {
-- ['iron-stick'] = {
-- overallWeight = 1,
-- minLambda = 0,
-- maxLambda = 0.5,
-- shape = 'uniform', -- a uniform raffle weight of 1, if lambda is between 0 and 1
-- },
-- ['coal'] = {
-- overallWeight = 3,
-- minLambda = 0,
-- maxLambda = 0.5,
-- shape = 'density', -- a uniform raffle weight of 6, if lambda is between 0 and 1
-- },
-- ['copper-wire'] = {
-- overallWeight = 1,
-- minLambda = 0,
-- maxLambda = 1,
-- shape = 'bump', -- the raffle weight is a ⋀ shape, going from (0, 0) to (0.5, 2) to (1, 0)
-- condition = function(x) return x == 'copperIsland' end, --this optional key performs a check on extraConditionParameter to see whether this raffle value should be included at all
-- },
-- }
local raffle = {}
for k, v in pairs(data) do
if (not v.shape) or (v.shape == 'uniform' or v.shape == 'flat') then
if (not v.minLambda) or (lambda >= v.minLambda) then
if (not v.maxLambda) or (lambda <= v.maxLambda) then
if (not v.condition) or (extraConditionParameter and v.condition(extraConditionParameter)) then
raffle[k] = v.overallWeight
end
end
end
elseif (v.shape == 'density') then
if v.minLambda and v.maxLambda and v.maxLambda ~= v.minLambda and lambda >= v.minLambda and lambda <= v.maxLambda then
if (not v.condition) or (extraConditionParameter and v.condition(extraConditionParameter)) then
raffle[k] = v.overallWeight / (v.maxLambda - v.minLambda)
end
end
elseif (v.shape == 'bump') then
if v.minLambda and v.maxLambda and lambda >= v.minLambda and lambda <= v.maxLambda then
if (not v.condition) or (extraConditionParameter and v.condition(extraConditionParameter)) then
if v.minLambda == v.maxLambda and lambda == v.minLambda then
raffle[k] = v.overallWeight
else
local midpoint = (v.minLambda + v.maxLambda) / 2
local peak = 2 * v.overallWeight
local slope = peak / ((v.maxLambda - v.minLambda) / 2)
local difference = Math.abs(lambda - midpoint)
raffle[k] = peak * (1 - difference * slope)
end
end
end
end
end
return Public.raffle2(raffle)
end
-- a function that accepts more abbreviated raffle data:
function Public.LambdaRaffleFromAbbreviatedData(abbreviatedData, lambda, extraConditionParameter)
-- example_argument = {
-- ['iron-stick'] = {
-- 1, 0, 1, 'uniform'
-- },
-- ['copper-plate'] = {
-- 1, 0, 1, 'uniform', function(x) return x == 'copperIsland' end
-- },
-- }
local data = {}
for k, v in pairs(abbreviatedData) do
data[k] = {
overallWeight = v[1],
minLambda = v[2],
maxLambda = v[3],
shape = v[4],
condition = v[4],
}
end
return Public.LambdaRaffle(data, lambda, extraConditionParameter)
end
return Public

View File

@ -1,3 +1,4 @@
-- data:extend(
-- {
-- {

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Balance = require 'maps.pirates.balance'
local _inspect = require 'utils.inspect'.inspect
@ -6,53 +8,40 @@ 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'
local SurfacesCommon = require 'maps.pirates.surfaces.common'
-- local Server = require 'utils.server'
local Public = {}
local enum = {
DECKHAND = 1,
FISHERMAN = 2,
SCOUT = 3,
SAMURAI = 4,
MERCHANT = 5,
SHORESMAN = 6,
BOATSWAIN = 7,
PROSPECTOR = 8,
LUMBERJACK = 9,
MASTER_ANGLER = 10,
WOOD_LORD = 11,
CHIEF_EXCAVATOR = 12,
HATAMOTO = 13,
IRON_LEG = 14,
QUARTERMASTER = 15,
DREDGER = 16,
SMOLDERING = 17,
GOURMET = 18,
DECKHAND = 'deckhand',
FISHERMAN = 'fisherman',
SCOUT = 'scout',
SAMURAI = 'samurai',
MERCHANT = 'merchant',
SHORESMAN = 'shoresman',
BOATSWAIN = 'boatswain',
PROSPECTOR = 'prospector',
LUMBERJACK = 'lumberjack',
MASTER_ANGLER = 'master_angler',
WOOD_LORD = 'wood_lord',
CHIEF_EXCAVATOR = 'chief_excavator',
HATAMOTO = 'hatamoto',
IRON_LEG = 'iron_leg',
QUARTERMASTER = 'quartermaster',
DREDGER = 'dredger',
SMOLDERING = 'smoldering',
GOURMET = 'gourmet',
}
Public.enum = enum
Public.Class_List = {
enum.DECKHAND,
enum.FISHERMAN,
enum.SCOUT,
enum.SAMURAI,
enum.MERCHANT,
enum.SHORESMAN,
enum.BOATSWAIN,
enum.PROSPECTOR,
enum.LUMBERJACK,
enum.MASTER_ANGLER,
enum.WOOD_LORD,
enum.CHIEF_EXCAVATOR,
enum.HATAMOTO,
enum.IRON_LEG,
enum.QUARTERMASTER,
enum.DREDGER,
enum.SMOLDERING,
enum.GOURMET,
}
-- function Public.Class_List()
-- local ret = {}
-- for _,v in pairs(enum) do
-- ret[#ret + 1] = v
-- end
-- end
Public.display_form = {
Public.eng_form = {
[enum.DECKHAND] = 'Deckhand',
[enum.FISHERMAN] = 'Fisherman',
[enum.SCOUT] = 'Scout',
@ -63,7 +52,7 @@ Public.display_form = {
[enum.PROSPECTOR] = 'Prospector',
[enum.LUMBERJACK] = 'Lumberjack',
[enum.MASTER_ANGLER] = 'Master Angler',
[enum.WOOD_LORD] = 'Lord of the Woods',
[enum.WOOD_LORD] = 'Wood Lord',
[enum.CHIEF_EXCAVATOR] = 'Chief Excavator',
[enum.HATAMOTO] = 'Hatamoto',
[enum.IRON_LEG] = 'Iron Leg',
@ -72,26 +61,94 @@ Public.display_form = {
[enum.SMOLDERING] = 'Smoldering',
[enum.GOURMET] = 'Gourmet',
}
Public.explanation = {
[enum.DECKHAND] = 'They move faster and generate ore for the cabin whilst onboard above deck.',
[enum.FISHERMAN] = 'They fish at greater distance.',
[enum.SCOUT] = 'They are faster, but frail and deal less damage.',
[enum.SAMURAI] = 'They are tough, and *with no weapon equipped* fight well by melee, but poorly otherwise.',
[enum.MERCHANT] = 'They generate 50 doubloons per league.',
[enum.SHORESMAN] = 'They move slightly faster and generate ore for the cabin whilst offboard.',
[enum.BOATSWAIN] = 'They move faster and generate ore for the cabin whilst below deck.',
[enum.PROSPECTOR] = 'They find more resources when handmining.',
[enum.LUMBERJACK] = 'They find more resources when chopping trees.',
[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.',
[enum.HATAMOTO] = 'They are very tough, and *with no weapon equipped* fight well by melee, but poorly otherwise.',
[enum.IRON_LEG] = 'They are very resistant to damage when carrying 3500 iron ore.',
[enum.QUARTERMASTER] = 'They give nearby crewmates extra physical attack, and generate ore for the cabin for each one.',
[enum.DREDGER] = 'They find surprising items when they fish.',
[enum.SMOLDERING] = 'They periodically convert wood into coal, if they have less than 50 coal.',
[enum.GOURMET] = 'They generate ore for the cabin by eating fish in fancy locations.',
}
function Public.display_form(class)
return {'pirates.class_' .. class}
end
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
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
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'},
-- }
-- Public.explanation = {
-- [enum.DECKHAND] = {'pirates.class_deckhand_explanation'},
-- }
-- 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 = {
[enum.FISHERMAN] = {enum.MASTER_ANGLER},
@ -104,7 +161,7 @@ Public.class_unlocks = {
Public.class_purchase_requirement = {
[enum.MASTER_ANGLER] = enum.FISHERMAN,
[enum.WOOD_LORD] = enum.LUMBERJACK,
-- [enum.CHIEF_EXCAVATOR] = enum.PROSPECTOR,
[enum.CHIEF_EXCAVATOR] = enum.PROSPECTOR,
[enum.HATAMOTO] = enum.SAMURAI,
[enum.DREDGER] = enum.MASTER_ANGLER,
}
@ -121,14 +178,32 @@ function Public.initial_class_pool()
enum.SAMURAI,
-- enum.MERCHANT, --not interesting, breaks coin economy
enum.BOATSWAIN,
enum.PROSPECTOR,
-- enum.PROSPECTOR, --lumberjack is just more fun
enum.LUMBERJACK,
enum.IRON_LEG,
-- enum.SMOLDERING,
-- enum.SMOLDERING, --tedious
enum.GOURMET,
}
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()
@ -137,7 +212,7 @@ function Public.assign_class(player_index, class, self_assigned)
if not memory.classes_table then memory.classes_table = {} end
if memory.classes_table[player_index] == class then
Common.notify_player_error(player, 'Class error: You\'re already a ' .. Public.display_form[class] .. '.')
Common.notify_player_error(player, {'pirates.error_class_assign_redundant', Public.display_form(class)})
return false
end
@ -149,43 +224,39 @@ function Public.assign_class(player_index, class, self_assigned)
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])'
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]]))
Common.notify_force_light(force,{'pirates.class_take_spare', player.name, Public.display_form(memory.classes_table[player_index]), Public.explanation(memory.classes_table[player_index])})
else
message = 'A spare %s class was given to %s. [font=scenario-message-dialog](%s)[/font]'
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]]))
Common.notify_force_light(force,{'pirates.class_give_spare', Public.display_form(memory.classes_table[player_index]), player.name, Public.explanation(memory.classes_table[player_index])})
end
end
memory.spare_classes = Utils.ordered_table_with_single_value_removed(memory.spare_classes, class)
return true
else
Common.notify_player_error(player, 'Class error: No spare class of that type is available.')
Common.notify_player_error(player, {'pirates.error_class_assign_unavailable_class'})
return false
end
end
function Public.try_renounce_class(player, whisper_failure_message, override_message)
function Public.try_renounce_class(player, whisper_failure_message, impersonal_bool)
local memory = Memory.get_crew_memory()
local force = memory.force
if force and force.valid and player and player.index then
if memory.classes_table and memory.classes_table[player.index] then
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]]))
if impersonal_bool then
Common.notify_force_light(force,{'pirates.class_becomes_spare', Public.display_form(memory.classes_table[player.index])})
else
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]]))
Common.notify_force_light(force,{'pirates.class_give_up', player.name, Public.display_form(memory.classes_table[player.index])})
end
end
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player.index]
memory.classes_table[player.index] = nil
elseif whisper_failure_message then
Common.notify_player_error(player, 'Class error: You don\'t have any class to give up.')
Common.notify_player_error(player, {'pirates.class_give_up_error_no_class'})
end
end
end
@ -208,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 = Public.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}}
@ -224,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)
@ -244,41 +318,69 @@ 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
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
multiplier = 1.6
elseif tile.name == CoreData.walkway_tile then
multiplier = 1
elseif tile.name == 'orange-refined-concrete' then
multiplier = 0.5
elseif tile.name == CoreData.enemy_landing_tile then
multiplier = 0.33
elseif tile.name == CoreData.static_boat_floor then
multiplier = 0.1
end
if multiplier > 0 then
local timescale = 60*30 * Math.max((Balance.game_slowness_scale())^(2/3),0.8)
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))))
memory.gourmet_recency_tick = Math.max(memory.gourmet_recency_tick, game.tick - timescale*10) + timescale
else
multiplier = multiplier * 5
memory.gourmet_recency_tick = game.tick - timescale*10 + timescale
local multiplier = 0
local surfacedata = SurfacesCommon.decode_surface_name(player.surface.name)
if surfacedata.type == SurfacesCommon.enum.CABIN then
multiplier = 0.25
elseif surfacedata.type == SurfacesCommon.enum.CROWSNEST then
multiplier = 0.15
else
local tile = player.surface.get_tile(player.position)
if tile.valid then
if tile.name == CoreData.world_concrete_tile then
multiplier = 1.5
elseif tile.name == 'cyan-refined-concrete' then
multiplier = 1.6
elseif tile.name == CoreData.walkway_tile then
multiplier = 1
elseif tile.name == 'orange-refined-concrete' then
multiplier = 0.5
elseif tile.name == CoreData.enemy_landing_tile then
multiplier = 0.3
elseif tile.name == CoreData.static_boat_floor then
multiplier = 0.1
end
Public.class_ore_grant(player, 10 * multiplier, true)
end
end
if multiplier > 0 then
local timescale = 60*30 * Math.max((Balance.game_slowness_scale())^(2/3),0.8)
if memory.gourmet_recency_tick then
multiplier = multiplier *Math.clamp(0.2, 5, (1/5)^((memory.gourmet_recency_tick - game.tick)/(60*300)))
memory.gourmet_recency_tick = Math.max(memory.gourmet_recency_tick, game.tick - timescale*10) + timescale
else
multiplier = multiplier * 5
memory.gourmet_recency_tick = game.tick - timescale*10 + timescale
end
Public.class_ore_grant(player, 10 * multiplier, Balance.gourmet_ore_scaling_enabled)
end
end
end
end
function Public.lumberjack_bonus_items(give_table)
local memory = Memory.get_crew_memory()
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
elseif Math.random(2) == 1 then
if Math.random(5) == 1 then
give_table[#give_table + 1] = {name = 'copper-ore', count = 1}
else
give_table[#give_table + 1] = {name = 'iron-ore', count = 1}
end
end
end
local event = require 'utils.event'
event.add(defines.events.on_player_used_capsule, class_on_player_used_capsule)

View File

@ -1,3 +1,4 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Session = require 'utils.datastore.session_data'
local Antigrief = require 'utils.antigrief'
@ -36,19 +37,18 @@ function Public.make_officer(captain, player)
if Common.validate_player(player) then
memory.officers_table[player.index] = true
local message = (captain.name .. ' made ' .. player.name .. ' an officer.')
Common.notify_force_light(force, message)
Common.notify_force_light(force,{'pirates.roles_make_officer', captain.name, player.name})
Public.update_privileges(player)
else
Common.notify_player_error(captain, 'Command error: Player is invalid.')
Common.notify_player_error(captain,{'pirates.roles_make_officer_error_1'})
return false
end
else
Common.notify_player_error(captain, 'Command error: Can\'t promote yourself to officer.')
Common.notify_player_error(captain,{'pirates.roles_make_officer_error_2'})
return false
end
else
Common.notify_player_error(captain, 'Command error: Player is not a crewmember.')
Common.notify_player_error(captain,{'pirates.roles_make_officer_error_3'})
return false
end
end
@ -61,16 +61,15 @@ function Public.unmake_officer(captain, player)
if memory.officers_table[player.index] then
memory.officers_table[player.index] = nil
local message = (captain.name .. ' unmade ' .. player.name .. ' an officer.')
Common.notify_force_light(force, message)
Common.notify_force_light(force,{'pirates.roles_unmake_officer', captain.name, player.name})
Public.update_privileges(player)
return true
else
Common.notify_player_error(captain, 'Command error: Player isn\'t an officer.')
Common.notify_player_error(captain,{'pirates.roles_unmake_officer_error_1'})
return false
end
else
Common.notify_player_error(captain, 'Command error: Player is not a crewmember.')
Common.notify_player_error(captain,{'pirates.roles_unmake_officer_error_2'})
return false
end
end
@ -83,7 +82,7 @@ function Public.revoke_class(captain, player)
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player.index]
memory.classes_table[player.index] = nil
Common.notify_force_light(force, string.format('%s revoked %s from %s.', captain.name, Classes.display_form[memory.classes_table[player.index]], player.name))
Common.notify_force_light(captain,{'pirates.class_revoke', captain.name, Classes.display_form(memory.classes_table[player.index]), player.name})
end
end
@ -103,7 +102,7 @@ function Public.tag_text(player)
local classes_table = memory.classes_table
if classes_table and classes_table[player.index] then
tags[#tags + 1] = Classes.display_form[classes_table[player.index]]
tags[#tags + 1] = Classes.eng_form[classes_table[player.index]]
end
for i, t in ipairs(tags) do
@ -125,33 +124,38 @@ end
-- function Public.get_classes_print_string()
-- local str = 'Current class Descriptions:'
-- for i, class in ipairs(Classes.Class_List) do
-- for i, class in pairs(Classes.enum) do
-- str = str .. '\n' .. Classes.display_form[class] .. ': ' .. Classes.explanation[class] .. ''
-- end
-- return str
-- end
function Public.get_class_print_string(class)
function Public.get_class_print_string(class, full)
for _, class2 in ipairs(Classes.Class_List) do
if Classes.display_form[class2]:lower() == class:lower() then
local str = ''
str = str .. Classes.display_form[class2] .. ': '
if Classes.class_purchase_requirement[class2] then
str = str .. 'An upgrade of ' .. Classes.display_form[Classes.class_purchase_requirement[class2]] .. '. '
for _, class2 in pairs(Classes.enum) do
if Classes.eng_form[class2]:lower() == class:lower() or class2 == class:lower() then
local explanation
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]), explanation}
else
return {'pirates.class_explanation', Classes.display_form(class2), explanation}
end
str = str .. Classes.explanation[class2]
return str
end
end
if class:lower() == 'officer' then
return 'Officer: Assigned by the captain, officers can use the Captain\'s shop and access privileged chests.'
return {'pirates.class_explanation', {'pirates.role_officer'}, {'pirates.role_officer_description'}}
end
if class:lower() == 'captain' then
return 'Captain: 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.'
return {'pirates.class_explanation', {'pirates.role_captain'}, {'pirates.role_captain_description'}}
end
return nil
@ -190,19 +194,20 @@ function Public.player_confirm_captainhood(player)
local captain_index = memory.playerindex_captain
if not (player.index == captain_index) then
Common.notify_player_error(player, 'Command error: You\'re not the captain.')
Common.notify_player_error(player,{'pirates.roles_confirm_captain_error_1'})
else
if memory.captain_acceptance_timer then
memory.captain_acceptance_timer = nil
local force = player.force
if force and force.valid then
local message = (player.name .. ' accepted the role of captain.')
local message = {'pirates.roles_confirm_captain', player.name}
Common.notify_force(force, message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.derp .. '[' .. memory.name .. '] ' .. message)
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.derp .. '[' .. memory.name .. '] ',message}, true)
end
else
Common.notify_player_expected(player, 'Command error: You\'re not temporary, so you don\'t need to accept.')
Common.notify_player_error(player,{'pirates.roles_confirm_captain_error_2'})
end
end
end
@ -221,7 +226,7 @@ function Public.player_left_so_redestribute_roles(player)
-- end
end
Classes.try_renounce_class(player, false, "A %s class is now spare.")
Classes.try_renounce_class(player, false, true)
end
@ -230,15 +235,16 @@ function Public.renounce_captainhood(player)
local memory = Memory.get_crew_memory()
if #Common.crew_get_crew_members() == 1 then
Common.notify_player_error(player, 'Command error: But you\'re the only crew member...')
Common.notify_player_error(player,{'pirates.roles_renounce_captain_error_1'})
else
local force = memory.force
global_memory.playerindex_to_captainhood_priority[player.index] = nil
if force and force.valid then
local message = (player.name .. ' renounces their title of captain.')
local message = {'pirates.roles_renounce_captain', player.name}
Common.notify_force(force, message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.ree1 .. '[' .. memory.name .. '] ' .. message)
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.ree1 .. '[' .. memory.name .. '] ',message}, true)
end
Public.assign_captain_based_on_priorities(player.index)
@ -252,9 +258,11 @@ function Public.resign_as_officer(player)
if memory.officers_table and memory.officers_table[player.index] then
memory.officers_table[player.index] = nil
local message = (player.name .. ' resigns as an officer.')
local message = {'pirates.roles_resign_officer', player.name}
Common.notify_force(force, message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.ree1 .. '[' .. memory.name .. '] ' .. message)
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.ree1 .. '[' .. memory.name .. '] ',message}, true)
else
log('Error: player tried to resign as officer despite not being one.')
end
@ -282,9 +290,13 @@ function Public.pass_captainhood(player, player_to_pass_to)
local force = memory.force
if not (force and force.valid) then return end
local message = string.format("%s has passed their captainhood to %s.", player.name, player_to_pass_to.name)
local message = {'pirates.roles_pass_captainhood', player.name, player_to_pass_to.name}
Common.notify_force(force, message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.spurdo .. '[' .. memory.name .. '] ' .. message)
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.spurdo .. '[' .. memory.name .. '] ',message}, true)
Public.make_captain(player_to_pass_to)
end
@ -297,9 +309,10 @@ function Public.afk_player_tick(player)
local force = memory.force
if force and force.valid then
local message = string.format(player.name .. ' was afk.')
local message = {'pirates.roles_lose_captainhood_by_afk', player.name}
Common.notify_force(force, message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.loops .. '[' .. memory.name .. '] ' .. message)
Server.to_discord_embed_raw({'',CoreData.comfy_emojis.loops .. '[' .. memory.name .. '] ',message}, true)
end
if #Common.crew_get_nonafk_crew_members() == 1 then --don't need to bounce it around
@ -353,7 +366,7 @@ function Public.assign_captain_based_on_priorities(excluded_player_index)
if not captain_index then
captain_index = crew_members[1]
captain_name = game.players[captain_index].name
Common.notify_force(force,'Looking for a suitable captain...')
Common.notify_force(force,{'pirates.roles_notify_looking_for_captain'})
end
if captain_index then
@ -365,14 +378,17 @@ function Public.assign_captain_based_on_priorities(excluded_player_index)
end
if #Common.crew_get_crew_members() > 1 then
local messages = {
"would you like to be captain?",
"would you like to be captain?",
"captain?",
"is it your turn to be captain?",
}
local message = captain_name .. ', ' .. messages[Math.random(#messages)]
Common.notify_force_light(force, message .. ' If yes say /ok')
local rng = Math.random(4)
local message
if rng <= 2 then
message = {'pirates.roles_ask_player_about_captainhood_variant_1', captain_name}
elseif rng <= 3 then
message = {'pirates.roles_ask_player_about_captainhood_variant_2', captain_name}
else
message = {'pirates.roles_ask_player_about_captainhood_variant_3', captain_name}
end
Common.notify_force_light(force, message)
-- Server.to_discord_embed_raw('[' .. memory.name .. ']' .. CoreData.comfy_emojis.spurdo .. ' ' .. message)
memory.captain_acceptance_timer = 72 --tuned
else
@ -406,7 +422,7 @@ function Public.captain_tax(captain_index)
if inv and inv.valid then
for _, i in pairs(items_to_req) do
local amount = inv.get_item_count(i)
if i == 'coin' then amount = Math.floor(amount/10) end
if i == 'coin' then amount = Math.floor(amount/100*Common.coin_tax_percentage) end
if amount and amount > 0 then
inv.remove{name=i, count=amount}
captain_inv.insert{name=i, count=amount}
@ -436,7 +452,7 @@ function Public.captain_tax(captain_index)
end
if any_taken then
local str = 'The captain taxed '
local str = {''}
local j = 1
for i = 1, #items_to_req do
local item = items_to_req[i]
@ -444,25 +460,28 @@ function Public.captain_tax(captain_index)
if count > 0 then
if j > 1 then
if i == #items_to_req then
str = str .. ' and '
str[#str+1] = {'pirates.separator_2'}
else
str = str .. ', '
str[#str+1] = {'pirates.separator_1'}
end
end
local display_name = item
if display_name == 'coin' then display_name = 'doubloons' end
if count >= 1000 then
str = str .. Utils.bignumber_abbrevform2(count) .. ' ' .. display_name
str[#str+1] = Utils.bignumber_abbrevform2(count)
str[#str+1] = ' '
str[#str+1] = display_name
else
str = str .. count .. ' ' .. display_name
str[#str+1] = count
str[#str+1] = ' '
str[#str+1] = display_name
end
j = j + 1
end
end
str = str .. '.'
Common.notify_force(memory.force, str)
Common.notify_force(memory.force, {'pirates.tax', str})
else
Common.notify_player_error(captain, 'No coins or game-critical found in crewmates\' inventories or cursor stacks.')
Common.notify_player_error(captain, {'pirates.tax_error_nothing'})
end
end
end

View File

@ -2,77 +2,154 @@
--luacheck ignores because tickinterval arguments are a code templating choice...
local Memory = require 'maps.pirates.memory'
local Gui = require 'maps.pirates.gui.gui'
local Ai = require 'maps.pirates.ai'
local Structures = require 'maps.pirates.structures.structures'
local Islands = require 'maps.pirates.surfaces.islands.islands'
local Boats = require 'maps.pirates.structures.boats.boats'
local Surfaces = require 'maps.pirates.surfaces.surfaces'
local Interface = require 'maps.pirates.interface'
local Roles = require 'maps.pirates.roles.roles'
local Classes = require 'maps.pirates.roles.classes'
local Progression = require 'maps.pirates.progression'
local Crowsnest = require 'maps.pirates.surfaces.crowsnest'
local Hold = require 'maps.pirates.surfaces.hold'
local Cabin = require 'maps.pirates.surfaces.cabin'
local Balance = require 'maps.pirates.balance'
local Common = require 'maps.pirates.common'
local CoreData = require 'maps.pirates.coredata'
local Overworld = require 'maps.pirates.overworld'
local Utils = require 'maps.pirates.utils_local'
local Crew = require 'maps.pirates.crew'
local Math = require 'maps.pirates.math'
local _inspect = require 'utils.inspect'.inspect
local Quest = require 'maps.pirates.quest'
local Public = {}
function Public.class_update_auxiliary_data(tickinterval)
local memory = Memory.get_crew_memory()
if not memory.classes_table then return end
local class_auxiliary_data = memory.class_auxiliary_data
local crew = Common.crew_get_crew_members()
local processed_players = {}
for _, player in pairs(crew) do
local player_index = player.index
local class = memory.classes_table[player_index]
if class and class == Classes.enum.IRON_LEG then
if (not class_auxiliary_data[player_index]) then class_auxiliary_data[player_index] = {} end
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')
if count and count >= Balance.iron_leg_iron_ore_required then
check = true
end
end
end
if check then
data.iron_leg_active = true
else
data.iron_leg_active = false
end
end
end
for k, _ in pairs(class_auxiliary_data) do
if not processed_players[k] then
class_auxiliary_data[k] = nil
end
end
end
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()
if not memory.quartermaster_renderings then
memory.quartermaster_renderings = {}
end
local processed_renderings = {}
local processed_players = {}
for _, player in pairs(crew) do
local player_index = player.index
if memory.classes_table[player_index] == Classes.enum.QUARTERMASTER then
local r = memory.quartermaster_renderings[player_index]
processed_renderings[player_index] = true
if Common.validate_player_and_character(player) then
if r and rendering.is_valid(r) then
rendering.set_target(r, player.character)
local class = memory.classes_table[player_index]
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
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 class == c then
if r and rendering.is_valid(r) then
rendering.set_target(r, player.character)
end
else
memory.quartermaster_renderings[player_index] = rendering.draw_circle{
surface = player.surface,
target = player.character,
color = CoreData.colors.quartermaster_rendering,
filled = false,
radius = Common.quartermaster_range,
only_in_alt_mode = true,
draw_on_ground = true,
}
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,
radius = Common.quartermaster_range,
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,
radius = (1 - Balance.samurai_damage_taken_multiplier)^2,
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,
radius = (1 - Balance.hatamoto_damage_taken_multiplier)^2,
only_in_alt_mode = false,
draw_on_ground = true,
}
}
elseif class == Classes.enum.IRON_LEG and memory.class_auxiliary_data[player_index] and memory.class_auxiliary_data[player_index].iron_leg_active then
class_renderings[player_index] = {
rendering = rendering.draw_circle{
surface = player.surface,
target = player.character,
color = CoreData.colors.toughness_rendering,
filled = false,
radius = (1 - Balance.iron_leg_damage_taken_multiplier)^2,
only_in_alt_mode = false,
draw_on_ground = true,
}
}
end
end
else
if r then
rendering.destroy(r)
memory.quartermaster_renderings[player_index] = nil
end
class_renderings[player_index] = nil
end
end
end
for k, r in pairs(memory.quartermaster_renderings) do
if not processed_renderings[k] then
rendering.destroy(r)
memory.quartermaster_renderings[k] = nil
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
end
end
end
@ -90,7 +167,7 @@ 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
--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
@ -99,16 +176,16 @@ function Public.update_character_properties(tickinterval)
-- end
if memory.classes_table[player_index] == Classes.enum.FISHERMAN then
max_reach_bonus = Math.max(max_reach_bonus, 10)
character.character_resource_reach_distance_bonus = 10
elseif memory.classes_table[player_index] == Classes.enum.MASTER_ANGLER or memory.classes_table[player_index] == Classes.enum.DREDGER then
max_reach_bonus = Math.max(max_reach_bonus, 16)
character.character_resource_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_resource_reach_distance_bonus = 0
character.character_reach_distance_bonus = 0
end
character.character_reach_distance_bonus = max_reach_bonus
--character.character_reach_distance_bonus = max_reach_bonus
end
local health_boost = 0 -- base health is 250
@ -130,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.75
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
@ -145,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()
@ -205,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

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
@ -46,11 +48,13 @@ Public.offers_default = {
{price = {{'coin', 720}}, offer = {type = 'give-item', item = 'gate', count = 10}},
{price = {{'coin', 120}}, offer = {type = 'give-item', item = 'storage-tank', count = 4}},
{price = {{'coin', 240}}, offer = {type = 'give-item', item = 'big-electric-pole', count = 8}},
{price = {{'coin', 240}}, offer = {type = 'give-item', item = 'steel-furnace', count = 4}},
{price = {{'coin', 360}}, offer = {type = 'give-item', item = 'stack-inserter', count = 3}},
{price = {{'coin', 900}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell', count = 9}},
{price = {{'coin', 960}}, offer = {type = 'give-item', item = 'flamethrower', count = 1}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 5}},
{price = {{'coin', 960}}, offer = {type = 'give-item', item = 'flamethrower', count = 1}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 6}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 6}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 6}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'flying-robot-frame', count = 1}},
}

View File

@ -1,5 +1,7 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
-- local CoreData = require 'maps.pirates.coredata'
local Classes = require 'maps.pirates.roles.classes'
@ -52,7 +54,7 @@ Public.market_permanent_offers = {
Public.market_sales = {
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'coal', count = 900}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine', count = 75}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine', count = 30}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine', count = 20}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell', count = 50}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'raw-fish', count = 300}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'laser-turret', count = 1}},
@ -111,6 +113,7 @@ Public.market_sales = {
function Public.create_dock_markets(surface, p)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
if not (surface and p) then return end
@ -123,7 +126,22 @@ function Public.create_dock_markets(surface, p)
e.rotatable = false
e.destructible = false
e.add_market_item{price = {{'repair-pack', 20}, {'coin', 1000}}, offer = {type = 'give-item', item = 'artillery-turret', count = 1}}
-- check if cannons need healing:
local need_healing
local cannons = game.surfaces[destination.surface_name].find_entities_filtered({type = 'artillery-turret'})
for _, c in pairs(cannons) do
local unit_number = c.unit_number
local healthbar = memory.boat.healthbars[unit_number]
if healthbar and healthbar.health < healthbar.max_health then
need_healing = true
break
end
end
if need_healing then
e.add_market_item{price = {{'repair-pack', 20}, {'coin', 1000}}, offer = {type = 'give-item', item = 'artillery-turret', count = 1}}
end
local upgrade_for_sale = Common.current_destination().static_params.upgrade_for_sale
if upgrade_for_sale then
@ -167,10 +185,10 @@ function Public.create_dock_markets(surface, p)
-- new class offerings:
if destination.static_params.class_for_sale then
e.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing", effect_description = 'Purchase the class ' .. Classes.display_form[destination.static_params.class_for_sale] .. '.'}}
e.add_market_item{price={{'coin', Balance.class_cost(true)}}, offer={type="nothing", effect_description = {'pirates.market_description_purchase_class', Classes.display_form(destination.static_params.class_for_sale)}}}
-- destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
-- text = 'Class available: ' .. Classes.display_form[destination.static_params.class_for_sale],
-- text = 'Class available: ' .. Classes.display_form(destination.static_params.class_for_sale),
-- surface = surface,
-- target = Utils.psum{e.position, {x = 0, y = -4}},
-- color = CoreData.colors.renderingtext_green,

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
@ -24,30 +26,34 @@ Public.Minimarket = require 'maps.pirates.shop.dock'
function Public.print_transaction(player, offer_itemname, offer_itemcount, price)
local s1 = ' traded away '
local s2 = ''
local type = 'traded away'
local s2 = {''}
local s3 = offer_itemcount .. ' ' .. offer_itemname
if offer_itemname == 'coin' then s1 = ' sold ' end
if offer_itemname == 'coin' then type = 'sold' end
for i, p in pairs(price) do
local p2 = {name = p.name, amount = p.amount}
if p2.name == 'raw-fish' then p2.name = 'fish' end
if p2.name == 'coin' then
s1 = ' bought '
type = 'bought'
p2.name = 'doubloons'
end
if i > 1 then
if i == #price then
s2 = s2 .. ' and '
s2[#s2+1] = {'pirates.separator_2'}
else
s2 = s2 .. ', '
s2[#s2+1] = {'pirates.separator_1'}
end
end
s2 = s2 .. p2.amount .. ' ' .. p2.name
s2[#s2+1] = p2.amount
s2[#s2+1] = ' '
s2[#s2+1] = p2.name
end
if s1 == ' sold ' or s1 == ' traded away ' then
Common.notify_force_light(player.force, player.name .. s1 .. s2 .. ' for ' .. s3 .. '.')
else
Common.notify_force_light(player.force, player.name .. s1 .. s3 .. ' for ' .. s2 .. '.')
if type == 'sold' then
Common.notify_force_light(player.force, {'pirates.market_event_sell', player.name, s2, s3})
elseif type == 'traded away' then
Common.notify_force_light(player.force, {'pirates.market_event_trade', player.name, s2, s3})
elseif type == 'bought' then
Common.notify_force_light(player.force, {'pirates.market_event_buy', player.name, s3, s2})
end
end
@ -162,7 +168,7 @@ function Public.event_on_market_item_purchased(event)
end
if thisPurchaseData.permission_level_fail then
Common.notify_player_error(player, string.format('Purchase error: You need to be a captain or officer to buy this.', player.name))
Common.notify_player_error(player, {'pirates.market_error_not_captain'})
-- refund:
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
@ -185,7 +191,7 @@ function Public.event_on_market_item_purchased(event)
log('error: healthbar ' .. unit_number .. ' not found')
end
end
Common.notify_force(force,string.format('[font=heading-1]%s repaired the ship\'s cannons.[/font]', player.name))
Common.notify_force(force,{'pirates.repaired_cannons', player.name})
market.remove_market_item(offer_index)
else
local upgrade_type = Common.current_destination().static_params.upgrade_for_sale
@ -209,14 +215,15 @@ function Public.event_on_market_item_purchased(event)
if required_class then
if not (memory.classes_table and memory.classes_table[player.index] and memory.classes_table[player.index] == required_class) then
ok = false
Common.notify_force_error(force, string.format('Class purchase error: You need to be a %s to buy this.', Classes.display_form[required_class]))
Common.notify_force_error(force, {'pirates.class_purchase_error_prerequisite_class',Classes.display_form(required_class)})
end
end
if ok then
if required_class then
if force and force.valid then
Common.notify_force_light(force,string.format('%s upgraded their class from %s to %s. ([font=scenario-message-dialog]%s[/font])', player.name, Classes.display_form[required_class], Classes.display_form[class_for_sale], Classes.explanation[class_for_sale]))
local message = {'pirates.class_upgrade', player.name, Classes.display_form(required_class), Classes.display_form(class_for_sale), Classes.explanation(class_for_sale)}
Common.notify_force_light(force,message)
end
else
-- check if they have a role already - renounce it if so
@ -225,7 +232,8 @@ function Public.event_on_market_item_purchased(event)
end
if force and force.valid then
Common.notify_force_light(force,string.format('%s bought the class %s. ([font=scenario-message-dialog]%s[/font])', player.name, Classes.display_form[class_for_sale], Classes.explanation[class_for_sale]))
local message = {'pirates.class_purchase', player.name, Classes.display_form(class_for_sale), Classes.explanation(class_for_sale)}
Common.notify_force_light(force, message)
end
end
@ -254,7 +262,7 @@ function Public.event_on_market_item_purchased(event)
refunds = refunds + 1
end
else
Common.notify_force_light(player.force, player.name .. ' bought ' .. thisPurchaseData.offer_giveitem_count .. ' ' .. thisPurchaseData.offer_giveitem_name .. ' for ' .. thisPurchaseData.price[1].amount .. ' ' .. thisPurchaseData.price[1].name .. '.')
Common.notify_force_light(player.force, {'pirates.market_event_buy', player.name, thisPurchaseData.offer_giveitem_count .. ' ' .. thisPurchaseData.offer_giveitem_name, thisPurchaseData.price[1].amount .. ' ' .. thisPurchaseData.price[1].name})
market.remove_market_item(offer_index)
end
@ -262,7 +270,7 @@ function Public.event_on_market_item_purchased(event)
else
if thisPurchaseData.in_captains_cabin and thisPurchaseData.permission_level_fail then
Common.notify_player_error(player, string.format('Purchase error: You need to be a captain or officer to buy this.', player.name))
Common.notify_player_error(player, {'pirates.market_error_not_captain_or_officer'})
-- refund:
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
@ -278,8 +286,7 @@ function Public.event_on_market_item_purchased(event)
if (thisPurchaseData.price and thisPurchaseData.price[1]) then
if not (thisPurchaseData.price[1].name and thisPurchaseData.price[1].name == 'burner-mining-drill') then --this one is too boring to announce
if thisPurchaseData.in_captains_cabin and thisPurchaseData.offer_type == 'nothing' then
local price_name = thisPurchaseData.price[1].name
Common.notify_force_light(player.force, player.name .. ' bought extra time at sea for ' .. thisPurchaseData.price[1].amount .. ' ' .. price_name .. '.')
Common.notify_force_light(player.force, {'pirates.market_event_buy', player.name, {'pirates.extra_time_at_sea'}, thisPurchaseData.price[1].amount .. ' ' .. thisPurchaseData.price[1].name})
else
Public.print_transaction(player, thisPurchaseData.offer_giveitem_name, thisPurchaseData.offer_giveitem_count, thisPurchaseData.price)
end
@ -289,7 +296,7 @@ function Public.event_on_market_item_purchased(event)
if thisPurchaseData.in_captains_cabin and thisPurchaseData.offer_type == 'nothing' then
local success = Crew.try_add_extra_time_at_sea(60 * 60)
if not success then
Common.notify_player_error(player, string.format('Purchase error: Reached the maximum allowed loading time.', player.name))
Common.notify_player_error(player, {'pirates.market_error_maximum_loading_time'})
-- refund:
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -25,12 +27,13 @@ Public[enum.RAFTLARGE] = require 'maps.pirates.structures.boats.raft_large.raft_
Public[enum.MERCHANT] = require 'maps.pirates.structures.boats.merchant_1.merchant_1'
Public.enum = enum
local enum_state = {
ATSEA_SAILING = 'at_sea',
APPROACHING = 'approaching',
LANDED = 'landed',
RETREATING = 'retreating',
LEAVING_DOCK = 'leaving',
ATSEA_SAILING = 'at_sea',
ATSEA_LOADING_MAP = 'waiting_for_load',
ATSEA_WAITING_TO_SAIL = 'waiting_for_sail',
DOCKED = 'docked',
}
Public.enum_state = enum_state
@ -773,7 +776,7 @@ local function process_entity_on_boat_unteleportable(memory, boat, newsurface, v
local force = memory.force
if not (force and force.valid) then return end
Common.notify_force(force,string.format('%s was pushed into water by a cannon.', name2), {r = 0.98, g = 0.66, b = 0.22})
Common.notify_force(force,{'pirates.death_pushed_into_water_by_cannon', name2}, {r = 0.98, g = 0.66, b = 0.22})
end
end
end
@ -960,24 +963,25 @@ local function process_entity_on_boat(memory, boat, newsurface, newposition, vec
unique_entities_list[#unique_entities_list + 1] = e
local name = e.name
-- if e.name and e.name == 'item-on-ground' then
-- log(_inspect{'hi', name, e.position})
-- end
if name == 'character' and e.player then -- characters with associated players treated as special case
if oldsurface_name == newsurface_name then
e.teleport(vector.x, vector.y)
else
local p = {e.position.x + vector.x, e.position.y + vector.y}
if e.player then --e.player being nil caused a bug once!
e.player.teleport(newsurface.find_non_colliding_position('character', p, 1.2, 0.2) or p, newsurface)
end
end
elseif Utils.contains(CoreData.unteleportable_names, name) or (name == 'entity-ghost' and Utils.contains(CoreData.unteleportable_names, e.ghost_name)) then
process_entity_on_boat_unteleportable(memory, boat, newsurface, vector, players_just_offside, oldsurface_name, newsurface_name, e, name)
if name and name == 'item-on-ground' then
Common.give_items_to_crew{{name = e.stack.name, count = e.stack.count}}
e.destroy()
else
process_entity_on_boat_teleportable(memory, boat, newsurface, newposition, vector, oldsurface_name, newsurface_name, electric_pole_neighbours_matrix, circuit_neighbours_matrix, e)
if name == 'character' and e.player then -- characters with associated players treated as special case
if oldsurface_name == newsurface_name then
e.teleport(vector.x, vector.y)
else
local p = {e.position.x + vector.x, e.position.y + vector.y}
if e.player then --e.player being nil caused a bug once!
e.player.teleport(newsurface.find_non_colliding_position('character', p, 1.2, 0.2) or p, newsurface)
end
end
elseif Utils.contains(CoreData.unteleportable_names, name) or (name == 'entity-ghost' and Utils.contains(CoreData.unteleportable_names, e.ghost_name)) then
process_entity_on_boat_unteleportable(memory, boat, newsurface, vector, players_just_offside, oldsurface_name, newsurface_name, e, name)
else
process_entity_on_boat_teleportable(memory, boat, newsurface, newposition, vector, oldsurface_name, newsurface_name, electric_pole_neighbours_matrix, circuit_neighbours_matrix, e)
end
end
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
@ -20,8 +22,8 @@ Public.entities = {
Public.market_pos = {x = -8.5, y = 0.5}
Public.landingtrack = {
offset = {x = -24, y = -10.5},
bp = [[0eNqV3M1u20YYRuF74VoB8g7J+dGtFFm4tpAKcCTDVn+CwPdeu2aLblrwWQo4psg5M5vz0fox/fz46+np+Xy5Tccf08vl7unT7frp6/P54f3zH9NxLofp+3QseT1M5/vr5WU6/vQGnr9e7h7fkdv3p9N0nM6307fpMF3uvr1/+v16fThdPt3/cnq5Te9/eHk4vV0rr18O0+38ePq4yNP15Xw7Xy/bN3180efXf67y9m33z6fb6e0K/wFH4CLwLPBC91yJbkR3ogct304zs2icReMsGmfROIvGmTTOpHEmjTNpnEnjIhoX0biIxkU0LqJxIY0LaVxI40IaF9K4isZVNK6icRWNq2hcSeNKGlfSuJLGlTRW0VhFYxWNVTRW0VhJYyWNlTRW0lhJYxONTTQ20dhEYxONjTQ20thIYyONjTR20dhFYxeNXTR20dhJYyeNnTR20thJ4xCNQzQO0ThE4xCNgzQO0jhI4yCNgzTms3jc6BBdiJ6JXuy+q+HN8G74sFXcqygkNCQ0JDQkNCQ0JjQmNCY0JjQmlNJOqO2E4k6o7oTyTqzvxAJPrPDEEk+s8YQiT6jyhDJPqPOEQk+s9MRST6z1xGJPrPaEck+o94SCT6j4hJJPrPnEok+s+sSyT6z7hMJPqPyE0k+o/YTiT6z+xPJPrP/EAlCsAIUSUKgBhSJQqAKFMlCsA8VCUKwExVJQrAWFYlCoBoVyUKgHhYJQrAjFklCsCcWiUKwKhbJQqAuFwlCoDIXS0Eav9pSIV8Ob4d3wYYr2+qf6FMpPof4UClChArXRK9HV1sRuJXYvwZtphnfDh/nf+y4FBbRCAa1QQCsU0AoFtI1eia5EN1tBe8zYc8YeNPakwUfthg/bXHt3LnXFQl2xUFcs1BULdcWNXomuRDeiu623LWFsDWOLGFvF2DLG1jG4kMN27t5jYa/p2Xt69qKevalnr+oVOkSFDlGhQ1ToEH3Qw+yYnpifmKCYoZiimKOYpJilmKbdJ5TifKE4XyjOF4rzheL8Rq9EV6Ib0Z3oYXZQptmM6Yz5jAmNGY0pjTmNSY1Z3X2gadxSaNxSaNxSaNyy0SvRlehGdCd6mB2UaTZjOmM+Y0JjRmNKY05jUncfUZpxFZpxFZpxbfRKdCW6Ed2JtvXefYpWO0WrnaLVTtFqp2i1U2QzzmIzzmIzzkKzv0Kzv41eia5EN6JtTQbRuzd6tY1ebaNX2+jVNnq1jW6z32Kz30Jjy41eia5E2313ogfRu/dis73YbC8224vN9mKzvWhj60JD0Y22azeiO9GD6N3bpdt26bZdum2XbtvF5taFBpcb3YjuRA+idxsdZnSY0WFGbfw704huozvRg+i9i/43HsOL4Xv/UZpGOhs9iN69LrF1sfHSTCF9o3ffunX3+f8i4JfDx28vHP/1Sw6H6bfT88tfFyg9SxulLXNdRumvr38Cd8bxwA==]],
offset = {x = -5, y = -0.5},
bp = [[0eNqV3MtuG0cQheF3mbUE+PRM3/QqgReKTTgEZEqQmIth6N0j2YMgmwTzLQkcNWfqr1rorwa/L78+/H56ej5frsvd9+Xlcv90e328/fJ8/vz++a/lbi03y7flruT1Zjl/ery8LHe/vAXPXy73D++R67en03K3nK+nr8vNcrn/+v7pz8fHz6fL7affTi/X5f0PL59Pb2fl9ePNcj0/nH4e8vT4cr6eHy/7N3348UUfXv855e3bPj2frqe3E/4jHAkXCa8S3uiZG6U7pQelJ5XvIJkIxgjGCMYIxgjGEMYQxhDGEMYQxiIYi2AsgrEIxiIYC2EshLEQxkIYC2FcBeMqGFfBuArGVTCuhHEljCthXAnjShg3wbgJxk0wboJxE4wbYdwI40YYN8K4EcYqGKtgrIKxCsYqGCthrISxEsZKGCthbIKxCcYmGJtgbIKxEcZGGBthbISxEcYuGLtg7IKxC8YuGDth7ISxE8ZOGDthHIJxCMYhGIdgHIJxEMZBGAdhHIRxEMYpGKdgnIJxCsYpGCdhnIRxEsZJGKf9+08aJ+RxQiInZHJCKifmcmIyJ2ZzYjon6HNM6JjRMaVjTsekDlod1DrodVDsmNkJqZ2Q2wnJnZDdCemdmN+JCZ6Y4YkpnpjjCUmekOUJaZ6Q5wmJnpjpiamemOuJyZ6Y7QnpnpDvCQmfkPEJKZ+Y84lJn5j1iWmfmPcJiZ+Q+Qmpn5D7CcmfmP2J6Z+Y/4kJoJgBCimgkAMKSaCQBQppoD1d7S0x3izeLT4sPg3RUf5kmkKqKeSaQrIpZJv2dKV0s5rYo8SeJfgw3eLD4tP4H20usmUhXRbyZSFhFjJme7pSulG6WwXtNWPvGXvR2JsGX3VYfFpzHe1c0okhnxgSiiGjGFKKe7pSulG6U3pYva2EsRrGihirYqyMsToGCzmtc49e6yGXW8jlFnK5hVxuIZe7pyulG6U7pQelp9ExPDE+MUAxQjFEMUYxSDFKMUyHJ5TkfCE5X0jOF5LzheT8nq6UbpTulB6UnkYHYRrNGM4YzxjQGNEY0hjTGNQY1cMDbVdp7S6tXaa127SFRrTQiBYa0UIjWmhEi41osREtNqLFRrTYiBYbUbxOjfep8UI13qimHVehHVehHdeerpRulO6UHpS2eh+eotWmaLUpWm2KVpui1abIdpzFdpzFdpyFdn+Fdn97ulK6UbpT2moyKX240Tdr9M0afbNG36zRN2t02/0W2/0WWlvu6UrpRml77kHpSenDvVitF6v1YrVerNaL1XrR1taFlqJ72s7ulB6UnpQ+3C7N2qVZuzRrl2btYnvrQovLPd0pPSg9KX2YaDei3Yh2I2rr30Iruj09KD0pfbjow4o+rOi2iyy00tnTk9KH6zKtLrZeWkmk7+mjj76ad1//TwJ+vPn5Owt3//rVhpvlj9Pzy48DysjWZ+m1blvt7fX1b9tV7YA=]],
}
return Public

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Data = require 'maps.pirates.structures.boats.merchant_1.data'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
@ -29,8 +31,8 @@ Public.entities = {
}
Public.landingtrack = {
offset = {x = 3.5, y = -7},
bp = [[0eNqV2M1qwkAYheF7mXWE+eZ/civFhdVBBjQJSSwVyb3XVBddtMV3JYHjBJ85m+NNvZ8uZRhrN6v2pqZuN2zmfnMc62F9/lStmEZd7x9+aVTd992k2rd7sB673WmNzNehqFbVuZxVo7rdeX265/ZjmYtav9QdynrOsm3UXE/lccDQT3Wuffd8y+b5Gr38dsafcWFxA0+neQvz7tW8MBxhOMJwBOIIxBGIoxmOZjia4WiIoyGOZjgZ2WREk5FMZjCZuWTGkhBLQiwJsSTGkhhLYiwRsUTEEhFLZCyRsUTGEhBLQCwBsQTGEhhLYCwesXjE4hGLZyyesXjG4hCLQywOsTjG4hiLYywWsVjEYhHLI21Rmv1Kj9IBpSNKJ5TO7HbgZbLbFHadwu7z5dqyWcJWCRslBtXWoNoaVFuDamtQbQ2qrUG1Nay2htUWbkY4GeliZJuITSK2iFBtBdVWUG0F1VZQbQXVVlBthdVWWG3pmod79Z/abpvHv0btj/+gGvVRxun7AJPExWyiDc5pa5blC6gg570=]],
offset = {x = -3, y = 0},
bp = [[0eNqV2M1qwkAUhuF7mXUEz/wnt1JcpDrIgE5CMi0Vyb3XqIsu2uK7ksCXCXm+s/Dkqt5PH2mccqmqu6q59OOmDpvjlA/r9ZfqRDfqcvtxS6Pyfiiz6t5uwXws/WmN1MuYVKdyTWfVqNKf16tbbj+lmtR6Uzmk9Zxl16iaT+lxwDjMueahPJ+yvT9ku/x2wh9hIWGNTmZpg9L2tbQQECEgQkAEgQgCEQSiCYgmIJqAaASiEYhGIIaAGAJiCIhBIAaBGARiCYglIJaAWARiEYhFII6AOALiCIhDIA6BOATiCYgnIJ6AeATiEYhHIIGABAISCEhAIAGBBAQSCUgkIJGARAQSEUhEIC0BaQlIS0AeYUPC6AUdCXsSDiQcSbhFpbAKUYeCShTU4sv/l9EGIWiFELRDPNMGpdlbOpT2KB1QOqJ0y9qBZbI2hdUprM+Xx5bteWzRY5ueoLEVNLaCxlbQ2AoaW0FjK2hshY2tsLGFqzjcxf9bxnfN4/NO9+NjUaM+0zTfD9BRbGh1cM5aF/yyfAPSTNjI]],
}
return Public

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Data = require 'maps.pirates.structures.boats.raft.data'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
@ -29,8 +31,8 @@ Public.entities = {
}
Public.landingtrack = {
offset = {x = 4.5, y = -7},
bp = [[0eNqV2M1qwkAYheF7mXWE+eZ/civFhdVBBjQJSSwVyb3XVBddtMV3JYHjBJ85m+NNvZ8uZRhrN6v2pqZuN2zmfnMc62F9/lStmEZd7x9+aVTd992k2rd7sB673WmNzNehqFbVuZxVo7rdeX265/ZjmYtav9QdynrOsm3UXE/lccDQT3Wuffd8y+b5Gr38dsafcWFxA0+neQvz7tW8MBxhOMJwBOIIxBGIoxmOZjia4WiIoyGOZjgZ2WREk5FMZjCZuWTGkhBLQiwJsSTGkhhLYiwRsUTEEhFLZCyRsUTGEhBLQCwBsQTGEhhLYCwesXjE4hGLZyyesXjG4hCLQywOsTjG4hiLYywWsVjEYhHLI21Rmv1Kj9IBpSNKJ5TO7HbgZbLbFHadwu7z5dqyWcJWCRslBtXWoNoaVFuDamtQbQ2qrUG1Nay2htUWbkY4GeliZJuITSK2iFBtBdVWUG0F1VZQbQXVVlBthdVWWG3pmod79Z/abpvHv0btj/+gGvVRxun7AJPExWyiDc5pa5blC6gg570=]],
offset = {x = -8, y = 0},
bp = [[0eNqVmctqwkAARf9l1hG88578SnFhNUhAk5CkpSL59/padGHBsxSOIznXxRm9mM/jVzOMbTeb+mKmbjus5n51GNv97fWPqa0qcza1wlKZdtd3k6k/rmB76LbHGzKfh8bUpp2bk6lMtz3dXl253djMjbm9qds313O0bCozt8fmccDQT+3c9t3zU9b3D1kvr074BxaBLTqZ0Q7R/j1aRIiIEBEhQkKEhAgJsUSIJUIsEWKREIuEWCTEESGOCHFEiENCHBLikBBPhHgixBMhHgnxSIhHQgIREoiQQIQEJCQgIQEJiURIJEIiERKRkIiERCQkESGJCElESEJCEhKSkJBMhGQiJBMhGQnJSEhGQgoRUoiQQoQUJKQgIYWFGUpVoVYVilWxWhXLVcFeZcHKipUlK2xWGK2sWoWyVahbhcJVrFzF0lWsXYXiVahehfJVrF/FAlasYIUSVqhhhSJWrGLFMlasY4VCVqhkhVJWrGXFYlasZoVyVqhnhYJWrGjFklasaYWiVqhqhbJWrGvFwlasbIXSVqhtheL2STtEs6cMiI6ITojOiC5sHTgmW1NsTrE93/7aoguI0A1E6ArypB2i2VMGREdEJ0RnRBe2DhyTrSk2p9ieb/9ajW6JFt0SLbolPmmHaPaUAdER0QnRGdGFrQPHZGuKzSm25+uv7aZ6/G1X//kTsDLfzTjdD7BZPhWbQvA+pLgsv9RK9k0=]],
}
return Public

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Data = require 'maps.pirates.structures.boats.raft_large.data'

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Data = require 'maps.pirates.structures.boats.sloop.data'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
-- local Math = require 'maps.pirates.math'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
@ -218,7 +220,7 @@ Public.small_radioactive_lab = {
{
type = 'tiles',
tile_name = 'tutorial-grid',
offset = {x = -5, y = -5},
offset = {x = 0, y = 0},
bp_string = [[0eNqdl8Fq4zAURf9FawciS7Yk72dR6K6zG4agJKIjxpGNrZQpxf/eKOkihWHGp6tgOM9+7+o+O/dN7PtzGKeYsujexJz8uMnD5nmKx3L9R3SyrsRr+VkqEQ9DmkX34wLG5+T7guTXMYhOxBxOohLJn8rVnIcUNvspHn6LUpeOodxqqf5b2fv9XUW9ouI8+RTPp80whbtKtfysRI59uPU7DnPMcUgfQ22vM5WRPjU8+vxLlEf+FZfbtby88QyvGa4YrhneMtww3DLcQd1Xn9PN2hCXDK8ZrhiuGW4Y7qAyq6VRTEnFPKnYrIp5UjFpFPSkglJqZhvNbKOZlJpJqZmUGkqpoZQNc2XD9rthB3XDG4avXpGWjdqy3tuvNGNg76ubN8zyhjVvWPOGWd6yL5Rlx2qZMpZZ0jIhLXt3WPgycEwax5bbsQVxTHjHhHfMko4J75iD3dfOaf2f5y1bkQ+e3l9BXkPe0f7XD0DjBc0XkrlT0shAMwMNDf9ODZcYec2b3V1SrkpMDZdIKr4/PH572s0n3/e7yR/j4A85voRdibGVeAnTfH1QbaU2rjaNbKRqt8vyDtor+Uc=]],
},
},
@ -239,7 +241,7 @@ Public.small_radioactive_centrifuge = {
{
type = 'tiles',
tile_name = 'tutorial-grid',
offset = {x = -5, y = -5},
offset = {x = 0, y = 0},
bp_string = [[0eNqdl82K2zAURt9Fawcs68/yvotCd+2uDMFJ1FSMIxtbGToMfveJk1mEobQ+WRnDuZZ0vivDfRO77hyGMaYsmjcxpXbY5H5zHONhef8jGikL8Xp5lHMh4r5Pk2h+XsB4TG23IPl1CKIRMYeTKERqT8vblPsUNrsx7p/FUpcOYfnUXPy3ch9SHuOv8zHcFVYrCs9jm+L5tOnH+0o1PxUixy7ctj30U8yxTx9nK29Hmz/te2jzb7Es+Ve8YrhiuGG4Zbhbi0tmRjIzkpm54ZrhhuGW4VBkvRavrnjJcMnwiuGK4ZrhhuGW4au9KyZSMZGKiVRMpGIiFROpHhHp1+KaedfMu2beNfOumXfNRGom0rCjGnZUw3rGsH+kYWYs+0da1mKWtZhl3i3zblmLWebdPuJ9dUc6FpNjMTkWk2MxORaTYzE5dpscS9WxVGsWU82818x7zbzXTGTNRNaPiFx9PTzz7tn18Cwmz2LyLCbProdnqXqWqmepepaqLOGsAsc4+c857jLrXofi5m6qL0TX7sJlbhY/vn778n07ndqu247tIfbtPseXsL0buQvxEsbpulxVS+185Yw0Utlynt8B8lo3wQ==]],
},
},
@ -259,7 +261,7 @@ Public.small_radioactive_reactor = {
{
type = 'tiles',
tile_name = 'tutorial-grid',
offset = {x = -9, y = -7},
offset = {x = 0, y = 0},
bp_string = [[0eNqdmV2Lm0AYhf/LXBvw1fnMfS8WetfelSVMkmE71GhQs3RZ/O+NiQuhlNanV8HwjJk55zia47vaN5d07nM7qu27Gtp43ozd5qXPx/n4p9qKL9Tb9cNNhcqHrh3U9tsVzC9tbGZkfDsntVV5TCdVqDae5qNh7Nq02ff58EPN49pjmk81Ff8c2V4OTYr9pk/xMHb9w+hqxehLH9t8OW26Pj2MrKfnQo25Sfe5n7shj7lrlwWWt/WZ6bfJn+P4Xc0/+UfcMtytxYWdXf7n7J7hgeFSQb5ey1d3nuEVw+FkNMMNwy3DHRSSCg8XK6tXW9/4kuHC8IrhmuGW4Y7hHipTQx4udr2xmjml2SWomVOaSa+Z9BpKY5g0hoXYMCUNU9IwJQ1T0sDbiIGht2y3scwoy4yyTHnLdhvLjLLMKMseDxYhoZICpaQ5EKi9rBbfseA49oTgWBIcS4JjSViWWkIearPeKget8swqz65xzzZjz7YEz3LjWW48y42HQfAwCB7uCR4Gx8O7uIdBCywKgXkbmFkBih+g+AFuyAGaFaBZAZolJdsWFl5D3tD5lHQAXQH4C19Czz4GrDdBoAkCTaCNC61caOdCSxehoRAaCtzrCA2FwCtZKvYML7A6EtgdCax3BPY7AguehfeQD1RPTQesVwh2QgJLIYG9jcDiZuEDnT9eMF3x+tux0HZIaD0kGpoM+6SFryBfQ15DnupjIe8hH6j+2DDqgFALhHoAQmpgSGFVJ7CrE1jWLbyFvIO8UIHAzmWoZbCEW/ga8hryDvIe8gHyQgUClyVsswTWWfL3xum5uL8X3j683S5UE/epuX739enzpy+74RSbZtfHY+7iYcyvaffxyrlQr6kfbj9WedEuVM6IkdqW0/QLDVP83g==]],
},
},
@ -279,7 +281,7 @@ Public.uranium_miners = {
{
type = 'tiles',
tile_name = 'tutorial-grid',
offset = {x = -10, y = -5},
offset = {x = 0, y = 0},
bp_string = [[0eNqdmMGOmzAQht/FZ5CwMdhw72Gl3tpbtYpIYqVWwSBwVl2t8u6FhEMqVa2/HkHfDDP/jPQbf4hjf3XT7EMU7YdYQjflccwvsz9vzz9Fq2Qm3kUr5S0T/jSGRbTfVtBfQtdvSHyfnGiFj24QmQjdsD0tcQwuP87+9ENsceHs1lRrin9Gut6d4hqXDz74cMnPs+/7pxwqIcd17oK/Dvk4u6fI8vaaieh79+hgGhcf/Rj2Not7l2v231uYuvhdbJ/8I14y3DDcpuL7hBiuGK4ZXjG8ZrhheLKQigmpmJCK7Yxiuiumu2K6l0z3kun+wJtUXLNiNMtesSWo73jBcJhdM7xieM1ww3DL8OQxGaa7YcoYpoxhylhWu2U7Y9nOWDYmy8bUsFYb1mrDWm2gexTQWAtolfBYIKnRy//Kn37uUGy4EvqrhJ4moantvIF8uj4l1KeE+kDflBrWo2E9Gp4sNZwvdHJZwfzQy3deQd5CPr1fA+uBLiehze28hbxMHwB0xp2vIF9D3kDeQj59IaD7Smi/O19CXkO+gryBfPr/ITR49VeDf80e9xbt0x1MJvru6Pr13deXz5++HJah6/vD3J392J2if3OH/XLj8LgfWQPe3LzcP6ms1KZRppKVLOvidvsF+s6+8A==]],
},
{

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Data = require 'maps.pirates.structures.island_structures.mattisso.data'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
local CoreData = require 'maps.pirates.coredata'
@ -17,7 +19,7 @@ Public.shelter1 = {
type = 'tiles',
tile_name = CoreData.world_concrete_tile,
offset = {x = 0, y = 0},
bp_string = [[0eNqV2t1qGkEYBuB7mWOF+Z/UWyk5sMkSFswquv0JwXtvTErpSUufoyCMa9CHj+H93tfw5fB1Op3nZQ2713BZ9qftetw+nefH2+sfYZf6Jrzc/lw3YX44Lpew+/x2cH5a9ofbkfXlNIVdmNfpOWzCsn++vbqsx2Xaft8fDuH2tuVxuj3per8J63yYPh5xOl7mdT4uvz5ne/f+Odu76++nvH3aw3lap7dn/PX4sOPdjjc7Xu14sePZjic6Hum0Pdv+cftW7Cu339Ow/K/EYc6HOR/mfJjzYc6HOR/mfJjzQc4HOR/kfJDzQc4HOR/kfJDzbs67Oe/mvJvzbs67Oe/mvJvzTs47Oe/kvJPzTs47Oe/kvJPzZs6bOW/mvJnzZs6bOW/mvJnzRs4bOW/kvJHzRs4bOW/kvJHzas6rOa/mvJrzas6rOa/mvJrzSs4rOa/kvJLzSs4rOa/kvJLzYs6LOS/mvJjzYs6LOS/mvJjzQs4LOS/kvJDzQs4LOS/kvJDzbM6zOc/mPJvzbM6zOc/mPJvzTM4zOc/kPJPzTM4zOc/kPJPzZM6TOU/mPJnzZM6TOU/mPJnzRM4TOU/kPJHzRM4TOU/kPInzSMwjKY+EPJLxSMQjCY8EPJLvKLyj6I6CO4rtKLSjyI4CO4prG982vW142+y20W2T2wa3zW0a2zS1aWjTzKaRTRObBjbNa7t+2+3bLt9297art9287eJt9266dtOtmy7ddOemKzfduOnCTfdti08sPbHwxLITi04sObHgxHITik0oNaHQhDITikwoMaHAhPISi78t/bbw27Jvi74t+bbg23Jvir0p9abQmzJvirwp8abAm/JuW1/a9tKWl7a7tNWlbS5tcWl7S1pb0taSlpa0s6SVJW0saWFJ+0qrn1j7xMon1j2x6ok1T6x4Yr0Tqp1Q64RKJ9Q5ocoJNU6ocEJ9E6sPWnvQyoPWHbTqoDUHrThovUGqDVJrkEqD1BmkyiA1Bqkw+I++4P3mozG++6N/vgnfpvPl/e35LtXxKY8yRkuxXq8/AdUS1bk=]],
bp_string = [[0eNqV2s2KG0cYhtF76bUG/FbXX+tWghcTWxiBLA0jOYkxunePbBOySchZNQ1fVy2+s3v62/L76cvh5fV4vi37b8v1/PzydLs8fXo9fny8/7Xs03fL18fjvluOHy7n67L/7W3w+On8fHqM3L6+HJb9crwdPi+75fz8+fF2vV3Oh6c/n0+n5fHZ+ePhcdL9/W65HU+Hn0e8XK7H2/Fy/nXPux/XvLv/fcbbXR9eD7fD2wn/MhwZLjK8ynCV4SbDXYaHDE8Z3mgptkLaYWiJoS2G1pj/uceI6ojqiOqI6ojqiOqI6ojqiOqI6pDqkOqQ6pDqkOqQ6iKqi6guorqI6iKqi6guorqI6iKqi6gupLqQ6kKqC6kupLqQ6lVUr6J6FdWrqF5F9SqqV1G9iupVVK+ieiXVK6leSfVKqldSvZLqKqqrqK6iuorqKqqrqK6iuorqKqqrqK6kupLqSqorqa6kupLqJqqbqG6iuonqJqqbqG6iuonqJqqbqG6kupHqRqobqW6kupHqLqq7qO6iuovqLqq7qO6iuovqLqq7qO6kupPqTqo7qe6kupPqIaqHqB6ieojqIaqHqB6ieojqIaqHqB6kepDqQaoHqR6kepDqKaqnqJ6ieorqKaqnqJ6ieorqKaqnqJ6kepLqSaonqZ6kepLqTVRvonoT1Zuo3kT1Jqo3Ub2J6k1Ub6J6I9Ubqd5I9UaqN1K9WYWhuBiqi6G8GOqLocAYKoyhxBhqjKHIGKqMscwY64yx0BgrjbHUGGyNFhutNlputN5owdGKoyVHa44WHa06YnbE7ojhEcsjpkdrj6H4GKqPofwY6o+hABkqkKEEGWqQoQgZqpCxDBnrkLEQGSuRsRQZa5GhGBmqkaEcGeqRoSAZKpKhJBlqkqEoGaqSsSwZ65KxMBkrk7E0GWuToTgZqpOhPBnqk6FAGSqUoUQZapShSBmqlLFMGeuUsVAZK5WxVBlrlaFYGaqVoVwZ6pWhYBkqlqFkGWqWoWgZqpaxbBnrlrFwGSuXsXSZ/2qX73c///je/+P/8d3yx+H1+uOAMlPHVkZrtbbR7/fvjZzNAg==]],
},
},
}
@ -37,7 +39,7 @@ Public.shelter2 = {
type = 'tiles',
tile_name = CoreData.world_concrete_tile,
offset = {x = 0, y = 0},
bp_string = [[0eNqd3c1uG0cQhdF3mTUJVDX7b/QqgReyNTEIUJRA0UkMQ+8eypGzCxCdlWHYTYKl4adC9b23fiyfT9+258vxfF3ufiwv5/vn/fVp//VyfHj7+1/LXS275fvbH6+75fjl6fyy3P12+4/Hr+f709t/uX5/3pa75XjdHpfdcr5/fPvby/XpvO3/vD+dlrdj54ft9kr5+mm3XI+n7Z+XeH56OV6PT+f399mX/PlG+8Prvy9z2X4/nreH/e1tv1y263Z7sf8+V/Bc2rmwY/huH/5wgcUMLGZgMcOKGVbMoGLmasX8dU7fL+1c2DF8tw9/uInFnFjMicWcVsxpxZxWzIHFHFjMgcUcVsxhxRxWzI7F7FjMjsXsVsxuxexWzIbFbFjMhsVsVsxmxWxWzIrFrFjMisWsVsxqxaxWzAMW84DFPGAxD1bMgxXzYMUs7x+OD6YeDDy44rmJ5wae63iu4bmK5w54jp8YO4ePC74bfjisJf7o8EnBBxO/B/i1w2+5UuXjGEsFZyo4U8GZCM5EcCaCMxGcieBMBCcOuhIHXYmDrrRBV9qgK23Q9X4Ma4k/OnxS8MHE7wF+7fBbrlT5OMZCwRkKzlBwBoIzEJyB4AwEZyA4A8GJQ+3EoXbiUDttqJ021E4caoeBMwycYeAMA2cYOMPAGQbOQHCGgXNFbq6IzRWpuRo0V2PmashcjZirAXM1XuK1Fd5a4aWV3VnZlZXdWK0EypU4uRImV6LkSpBciZErIXI1Qq4GyImAnAjIiYCcBshpgJwGyGmAnAbIaYDEq2i8icaLaLuHtmtou4WeBMhJgJwEyEmAnATISYCcBMhpgJwGyIGAHAjIgYAcBshhgBwGyGGAHAbIYYBEeQmqS1BcYtoSk5aYsmQQIAcBchAgBwFyECAHAXIQIIcBchggOwKyIyA7ArIbILsBshsguwGyGyC7ARIlY6gYQ8GY6cVMLmZqsU6A7ATIToDsBMhOgOwEyE6A7AbIboBsCMiGgGwIyGaAbAbIZoBsBshmgGwGSJSBogoURaCmATUJqClAGwGyESAbAbIRIBsBshEgGwGyGSCbAbIiICsCsiIgqwGyGiCrAbIaIKsBshogUdqNym4Udpuu22TdpuquBMhKgKwEyEqArATISoCsBMhqgKwGyF8ifD0Xdi5XPDfx3MBzHc81PFfx3AHPFTyHz0vi84KPCz4t+LDgs4KPCj4p+KDoc0LH7CGx97IPZlW0H5k9H/Yw2pNvXzP7TiNBEFjIR8Qx0h9/2eDvNvxVir+5sVH4cF9SsA8q2AcV7IMK9kEF+6CCfVDBPqhgH1SwD1K/pdot1W2JZkv0WqLVEp2WaLREnyXaLNFliSZL81iaxdIclmawNH+l2SvNXWnmSvNWmrUSnZVorCzWBxXrg4r1QcX6oGJ9ULE+qFgfVKwPKtYHJfZBiX1QYh+U2Acl9kGJfVBiH5TYByX2QWyfVhOgegDRAogOQDQAov8P7X/o/kPzH3r/0Ppnzj8z/pnvz2x/5voz0595/szyZ44/M/yh3w990tYHpfVBaX1QWh+U1gel9UFpfVBaH5TUB4W1QWFdUFgTFNYDhbVAYR1QWAMU1v+EtT+YgYAJCJh/YOkHln1gyQeWe2CpB5Z5YIkHlndgaQeUdUBJB5RzQCkHlHFACQeUb0DpBpRtQMkGlmtgqQZBXU5QkxPU4wS1OEEdTlCDE9TfBLU3Qd0NDnlwxoMjHpzw4IAH5zs43sHpDg53cLaDox2c7Nhgx+Y6NtaxqY4NdWymYyMdm+jYQIfmOTTOoWkODXNolkOjHJrk0CCH5jg0xrEpjg1xbIZjIxyb4NgAx+Y3Nr6x6Y0Nb2x2g1IeVPKgkAd1PCjjQRUPinhQw4MSHlTwoIAH9Tsm3zH1jol3TLtj0h1T7phwx3Q7Jtsh1Q6JdkizQ5IdUuyQYIf0OiTXIbUOiXVMq2NSHVPqmFDHdDom0zGVjol0TKNjEh1T6KBxB307aNsx146ZdsyzY5Ydc+yYYcf8OmbXMbcOmXXIq0NWHXLqkFGHfDpk0yGXDpl0yKNjFh1z6KC1H539aOw3X7/Z+s3Vb6Z+8/Sbpd8c/WboNz8/2fnJzU9mfvLyk5WfnPxk5CcfP9n4ycVvJn7z8GMIFGZAYQSUJUBZAJTlP1n8k6U/WfiTZT9Z9JMlP1HwE+U+UewTpT5R6BNlPlHkEyU+UeAT5T1Z3JOlPWFcKKaFYlioZYVaVKglhVpQqOWEWkyopYRaSKhlhFJEKCWEUkAo5YNSPCilg1I4KGWDUjQoJYNaMKjlgmKwPObKY6y8pcpbqLxlylukvCXKW6C85clbnLylyVOYPGXJU5Q8JclTkDzlyFOMPKXIU4g8ZchbhLwlyOMKItxAhAuIbP+QrR+y7UO2fMh2D9nqIds8ZIuHbO8QrR2irUO0dIh2DtHKIdo4RAuHaN8QrRuibUO2bMh2DeGyStxViasqbVOlLaq0PZW2ptK2VNqSSttRaSsqbUMlLaik/ZS0npK2U9JyStpNSaspaTMlLaakvZS2ltK2Uuq6c912rsvOcdc5rjrHTee46Bz3nOOac9xyjkvOcce5rTi3Dee24Nz2m9t6c9tubsvNbbe5rTa3zea42Bz3mqe6BdUuqH5BNAyiYxAtg+gZRNMgugbRNoi+QTQOmnPQrIPmHTTzoLkHzT5o/kEzEJqD0CyE6CFEE6H5UNKMKGlOlCQrSpIXJcmMkqZvThM4pymckyTOSRrnJJFzmjoyTR6Zpo9MEkgmKSSTJJJp2qo0cVWauipJXpWkr0oSWKUpM9KkGWnajCRxRpI6I0mekXavm3axm3azm3S1m3S3m3S5m3YrlHYtlHYvlHQxlHQzlHQ1lDZTThsqp02Vk8bKSXPlpMFysTlUsTlUsTlUoTlUoTlU+R9zqE+75XjdHm//9vn0bXu+HM/XZbf8sV1efr5OmVnHWsZhjJZRX1//Bgu6MZo=]],
bp_string = [[0eNqd3MGOHGUSReF3qXVb6rg3s7LSrzJiYXCBSmq3re6CGYT87rSNa3YjTX0rhCDaEByCIP+456/Dz0+/n7+8XJ6vh/d/HV6fP3x5d/387reXy8dvv/+fw/slD4c/v/3m68Ph8svn59fD+3+9/YmX354/PH37U65/fjkf3h8u1/Onw8Ph+cOnb7/3ev38fH737w9PT4dvZc8fz28/ab7+9HC4Xp7O//yIL59fL9fL5+cfv87j919mTl//+0Nezr9ens8f3739or+8nK/ntx/1v6p2qcojVQ1Vhap6X9VQD4d6ONTDoR4O9XCoh6EehnoY6mGoh6EehnpY6mGph6UelnpY6mGphwv1cKEeLtTDhXq4UA8X6uFKPVyphyv1cKUertTDlXp4pB4eqYdH6uGRenikHh6phxv1cKMebtTDjXq4UQ836uGJeniiHp6ohyfq4Yl6eKIe7t+rdimaR6oaqgpVUTNmoaqVqo5UtVHViaqIjRAbITZCbNi/KCE2QmyE2AixEWIjxEaJjRIbvfd/EB9lHv6ouncg3srGyuxv7d6ZeCtbrGy1sqOVbVZ2sjKjJEZJjJIYJTFKYpTEKIlREqMkRkmMkholNUruHpNDY3JsTI6NybExOTYmx8bk2JgcG5NjYxI/IuNXZPyMjN+R8UOyfUm+lRklMUpilMQoiVESo6RGSY2Su8dkaEzGxmRsTMbGZGxMxsZkbEzGxmRsTNo70dhD0dhL0dhT0dhb0dhj0a3MKIlREqMkRkmMkhglNUpqlNw9JktjsjYma2OyNiZrY7I2JmtjsjYma2PSnoLH3oLHHoPHXoPHnoPH3oNvZUZJjJIYJTFKYpTEKKlRUqPk7jG50JhcbEwuNiYXG5OLjcnFxuRiY3KxMbnYmLRrj7Fzj7F7j7GDj7GLj7GTj1uZURKjJEZJjJIYJTFKapTUKLl7TK40Jlcbk6uNydXG5GpjcrUxudqYXG1MrjYm7aBr7KJr7KRr7KZr7Khr7KrrVmaUxCiJURKjJEZJjJIaJTVK7h6TRxqTRxuTRxuTRxuTRxuTRxuTRxuTRxuTRxuTdrM5drQ5drU5drY5drc5drh5KzNKYpTEKIlREqMkRkmNkhold4/JjcbkZmNyszG52ZjcbExuNiY3G5ObjcnNxqSdZY/dZY8dZo9dZo+dZo/dZt/KjJIYJTFKYpTEKIlRUqOkRsndY/Kf6/NHqhqqsr/CUtVCVStVHalqo6oTVe32TxnhMDrG8BjjYwyQMULGEBljZAySMUpilARniFESoyRGSYySGCUxSmKUxCipUVKjBP9jWKOkRkmNkholNUpqlNQoWYyS5V5Kdtp9dtp9dtp9dtp9dtp9dtp9dtp9dtp9dtp9KCk5FpUcy0qOhSXH0pJjccmxvORYYHIsMTkWmRzLTI6FJsdSk2OxybHc5Fhwciw5ORadHMtOjoUnx9KTY/HJsfzkYIByt91nt91nt91nt91nt91nt91nt91nt91np90nj7L7/KiyXytUVapaqGqlqiNVbVR1oqrd/ikjHEbHGB5jfIwBMkbIGCJjjIxBMkZJjJLgDDFKYpTEKIlREqMkRkmMkhglNUpqlBT/U2OU1CipUVKjpEZJjZIaJYtRcvfuM7T7DO0+Q7vP0O4ztPsM7T5Du8/Q7jO0+5DqIKY6iKkOYqqDmOogpjqIqQ5iqoOY6iCmOoipDmKqg5jqIKY6CEpzTXUQUx3EVAcx1UFMdRBTHcRUBzHVQUx1cCszSmqU1CipUVKjpEZJjZLFKLl79wntPqHdJ7T7hHaf0O4T2n1Cu09o9wntPuQviflLYv6SmL8k5i+J+Uti/pKYvyTmLwl67lF0j6Z7VN2j6978JTF/ScxfEvOXxPwlMX9JzF8S85fE/CUxf8mtzCipUVKjpEZJjZIaJTVKFqPk7t2ntPuUdp/S7lPafUq7T2n3Ke0+pd2ntPuQlCgmJYpJiWJSopiUKCYlikmJYlKimJQoJiWKSYliUqKYlCgmJYpJiWJSopiUKCYlikmJYlKimJQoJiWKSYliUqJbmVFSo6RGSY2SGiU1SmqULEbJ3bsPOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qCKOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qAKOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qCKOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qAKOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qCKOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qAKOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qCKOahiDqqYgyrmoIo5qGIOqpiDKuagijmoYg6qmIMq5qAK2YlidqKYnShmJ4rZiWJ2opidKGYnitmJYnaimJ0oZieK2YlidqKYnShmJ4rZiWJ2opidKGYnitmJYnaimJ0oZicKiUxiIpOYyCQmMomJTGIik5jIJCYyiYlMYiKTmMgkJjKJiUxiIpOYyCQmMomJTGIik5jIJCYyiYlMYiKTmMgkJjIpOQ9qzoOa86DmPKg5D2rOg5rzoOY8qDkPas6DmvOg5jyoOQ9qzoOa86DmPKg5D2rOg5rzoOY8qDkPas6DmvOg5jwoxaNr8ehaPLoWj67Fo2vx6Fo8uhaPrsWja/HoWjy6Fo+uxaNr8ehaPLoWj67Fo2vx6Fo8uhaPrsWja/HoWjy6Fo8uJSlrScpakrKWpKwlKWtJylqSspakrCUpa0nKWpKylqSsJSlrScpakrKWpKwlKWtJylqSspakrCUpa0nKWpKylqSsxXBqMZxaDKcWw6nFcGoxnNrpdu10u3a6XTvdrp1u1063a9edtevO2nVn7bqzdt1Zu+6sHYDVDsBqB2C1A7DaAVjtAKx2I1K7EandiNRuRGo3IrUbkdozcu0ZufaMXHtGrj0j156Ray9NtZem2ktT7aWp9tJUe2la7GP0Yh+jF/sYvdjH6MU+Ri/2MXqx71WLfa9a7HvVYt+rFvtetfw/36t+ejhcrudPb3/s56ffz19eLs/Xw8Phj/PL6/cflNMs255tXZdl3Y5fv/4NUTZn6w==]],
},
{
type = 'static',
@ -48,7 +50,6 @@ Public.shelter2 = {
},
}
Public.lonely_storage_tank = {
name = 'lonely_storage_tank',
width = 4,
@ -78,76 +79,6 @@ Public.swamp_lonely_storage_tank = {
},
}
Public.covered1 = {
name = 'covered1',
width = 17,
height = 15,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = -9, y = -8},
bp_string = [[0eNqVmMGKwjAURf8l6wreJG2S/srgwtEgAW1L7Qwj0n8fqy5m4YBnJcKxHrxc7sOr+Tx+5WEs3WTaqzl322E19avDWPbL+x/TKlXmcnsJc2XKru/Opv24geXQbY8LMl2GbFpTpnwylem2p+XdjduNecpm+VC3z8tz5k1lpnLMjwcM/blMpe+e37K+f8l6fvWEf2AR2BLYEdgTuCZwQ+BA4EjghEJhEaIMhUIUSlEoRqEc9WaQIh0Q6YBIB0Q6INIBkQ6IdECkAyIdEOmAUAeEOiDUAaEOCHVAqANCHbCkA5Z0wCJri6wdsXbE2iFrh6w9sfbE2iNrj6xrYl0T6xpZ18i6IdYNsW6QdYOsA7EOxDog64CsI7GOxDoi64isE7FOxDoh68RuFnS4C13uYseW4LXFzi12b8GJZBspNJJCKyk2k2I7KTSUQkspNpViWyk0lkJrKTaXYnspNJhCiyk2mWKbKTSaQqspNptiuyk0nELL+aQtoh2iPaJrRLNfMCA6IjqxdGCYLE2xOMXyFAtULNG3S4HuMqHD7ElbRDtEe0TXiGa/YEB0RHRi6cAwWZpicYrlKRaoWKKvS7GpHv+Tt3/+da/Mdx7P9wfYKB+SDd41Ptk4z7+pVIVy]],
},
{
type = 'tiles',
tile_name = 'green-refined-concrete',
offset = {x = -1, y = 2},
bp_string = [[0eNqV0tsKwjAMBuB3yXWF9bCDfRXxYm5lFLa2tFUco+9uO70QVDCXgS9/CMkGl/mqnNcmgtwgmN4doj1MXo+lvoNsCawg60RAD9YEkKfM9GT6uYC4OgUSdFQLEDD9UqrsBq+igtJkRpVTaDoTiHpWzwBng47amteMap8h0reED0wxmGEw33GFwRSDGQZzDP5zQYHBNQY3v3E+/P4e8u3VCNyUD3s766hoj6wVjPOublJ6AP6T06c=]],
},
{
type = 'tiles',
tile_name = 'out-of-map',
offset = {x = -7, y = -6},
bp_string = [[0eNqd2s1Kw0AUhuF7mXWEfnPO/OVWxEXVIIGaljaKIrl3G3XhQqWvqxA4nUDOs3qbt3C7exoOx3GaQ/8WTtP2cDXvrx6O4/16/xJ6pS68ni+2dGG820+n0F+fB8eHabtbR+bXwxD6MM7DY+jCtH1c785zd8dhHsL6o+l+WM9Zbrowj7vh84DD/jTO4376esrm4yGb5acTfhkWGY5k2Miwk+FEhjMZLmS4kuGGlsJWiHaoC5coYknEkoglEUsilkQsiVgSsSRiScSSkCUhS0KWIrEUiaVILEViKRJLkViKxFIkliKxFImliCxFZCkiS0YsGbFkxJIRS0YsGbFkxJIRS0YsGbFkyJIhS4YsObHkxJITS04sObHkxJITS04sObHkxJIjS44sObKUiKVELCViKRFLiVhKxFIilhKxlIilRCwlZCkhSwlZysRSJpYysZSJpUwsZWIpE0uZWMrEUiaWMrKUkaVCdBSioxAdhegoREchOgrRUYiOQnQUoqMgHQXpqERHJToq0VGJjkp0VKKjEh2V6KhERyU6KtJRkY5GdDSioxEdjehoREcjOhrR0VDVQSlWqMUKxVihGiuUY4V6rFCQ1eYf77ui6ca2A5d56TZZaGWllaVW1lpZbGW1leVW1ltZcGXFFSZX2FxRRhXqqEIhVaikCqVUoZYqFFOFaqpQThXqqWJBVayoCkVSoUoqlEmFOqlQKBUqpUKpVKiVCsVSoVoqlktl/5Fy8Z+CqJgKJVOhZioUTYWqqVA2FeqmQuFUqJwKpVOxdioWT/VXPb3pPr906L99N9GF5+F4+jggVnlpsbhlb7Euyzuk5qn3]],
},
{
type = 'static',
force = 'environment',
offset = {x = 0, y = 0},
bp_string = [[0eNqlmNtuozAQht/F11Ax+IR5lVW1Io0VIRGDwOw2qnj3hbKHSGVghr2KUODz2Hwe+PkQl2b0XV+HKMoPMYSqS2Ob3vr6uhy/ixJsIh7zj54SUb+1YRDlt/nE+haqZjklPjovSlFHfxeJCNV9ORpiG3z6s2oasVwWrn4hTa+J8CHWsfYr5fPg8T2M94vv5xO2rk9E1w7zJW34XVD2oteKXvQ0JV8gOQuSbUMkCQL7EEWC5PsQTYLIfYghQdQ+xJIgeh9SkCBmH+JIELsPgYxEKQ4oNGfdAeWftP696/0wpOO8Z/pb386/6cU3ccO+Z4eTP/uwHWM3RrE1CFHqA6uBpjUceA00seHAbKCpDQduA01uOLAbaHqD2W9h4HgYpJo8Y7VCjVCAVwyG4fVli1Aki2IQiuJNCStG8zBYNYY1J4dQLItSIJTifxqRe25EdUD6UM60G5mwzHgYZMaS+dKBbFnJ0xuw9w75Zf2btppvwM6qA1C6v2Q6j06UKT06U571y+NkE2NPCPsXKj+Fvda9f1v/zo/1lWe2iCWMuHPvHNkKd35iKqO7lyPDGMIwcKbFSHQBDWEBVc6UFrFNyTO1G0Lt+HIp3j5RSOWalWhQjGFlGhRjWakGxRSsXINiHCvZYBidsbINigFWukExOSveoBjJyjcohvj0OdJYa16GQTmGF2JQjuWlGJRT8GIMynG8HINxDPPlauW8JutnoPLpo1Iifvh+WJ9BBSjrcqukUS4vpukXJhD2Zw==]],
},
},
}
Public.covered1.red_chest = {x = 2, y = 5}
Public.covered1.blue_chest = {x = 2, y = 6}
Public.covered1.walls = {
{x = -8, y = -5},
{x = -8, y = -4},
{x = -8, y = -3},
{x = 8, y = -5},
{x = 8, y = -4},
{x = 8, y = -3},
}
Public.covered1b = {
name = 'covered1b',
width = 17,
height = 15,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = -7, y = -6},
bp_string = [[0eNqVmM1qg0AURt9l1gby3ev/q5QsbDMUwaiobROC797YlpJFaXtWInwzzmHO4rtew2P3Esep7ZdQX8PcN+NuGXbPU3vc3s+hVpaEy+3haxLap6GfQ/1wC7bPfdNtkeUyxlCHdomnkIS+OW1v8zL0cffWdF3YlvXHuO20Jn8ujOdxivO864bmGKe7xbYekrC0Xfz8/jjM7dIO/dch9x9n3K/f+9wO+jTFJYbtmz+GRcJGwk7CKQlnJJyTcEHCJQlX6FLYFaI71D8vUcQlEZdEXBJxScQlEZdEXBJxScQlEZeEXBJyScglIy4ZccmIS0ZcMuKSEZeMuGTEJSMuGXHJkEuGXDLkkhOXnLjkxCUnLjlxyYlLTlxy4pITl5y45MglRy45ciklLqXEpZS4lBKXUuJSRgAzApgRwIwAZgQwJ4A5AcwJYE4AcwJYEMCCABYEsCCABQEsCWBJAEsCWBLAkgBWBLAigBUBrAhghYo0GjuF5k6hwVNo8hQaPcUGIjYRsZGIzURsKEJVXairC5V1obYuVNeFSqRQixSqkUI9UqhICtUboX4jVHCEGo5+qTiH5PNPWX33wy4Jr3GaP9ZbqbSorEjNvczydX0HDBNakQ==]],
},
{
type = 'static',
force = 'ancient-friendly',
offset = {x = 0, y = 0},
bp_string = [[0eNqV1e9qwyAQAPB3uc+mRBOjyauMMdJFipBqiHZrKL77YsqgjPnvUzi4+0W543zAeb6JZZXKwvAAo8alsrq6rHLy8R0GTBFs+6dxCOSnVgaGtz1RXtQ4+xS7LQIGkFZcAYEarz4yVitRfY/zDL5MTcJLDiULxX1ZhTHVrMdJrC/FxL0jEMpKK8XzCEewfajb9bxnDvi/nyNYtNlLtPq9zel5nfpEnT/OH4RkIXUcabKQJo60WQiJIzQLYXGky0L6OMKyEB5HeF6LEz3u85REk3GdxyQ6hDPHNjEtOG9wcZtgmqL5bwNKW6R0AYUWKTSgdEUKDyisSGEBhRcpONSkvojpA5uuLjsMCTC4jMGe2Tf5sfWHl8cHwZdYzVFBOG5ZT1hLmobTzrkfNM8jsg==]],
},
},
}
Public.covered1b.market = {x = -2, y = -5}
Public.covered1b.steel_chest = {x = 1, y = -5}
Public.covered1b.wooden_chests = {
{x = -5, y = 1},
{x = -4, y = 3},
{x = -5, y = 5},
}
Public.maze_defended_camp = {
@ -337,7 +268,7 @@ Public.maze_treasure = {
{
type = 'tiles',
tile_name = 'cyan-refined-concrete',
offset = {x = -1, y = -1},
offset = {x = 0, y = 0},
bp_string = [[0eNqVksEKgzAMht8l5wqmzrn1VcYOToMEtC21GxPpu691O+wwYb0EAl/+fJCscBvvZB1rD2qFWbe28KYYHPepf4KqBCyxBgHcGT2DukSMB92OCfCLJVDAniYQoNspdZHrHHmCNKR7iikYrgI8j/QOsGZmz0Z/dpTbjjL8StiBMQeW/8GYo4E5GpijIXM0ZI6G3NeI59mOqL4eQsCD3LyNyxMemrNsaqyxOpYhvAAnDLaS]],
},
{

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Data = require 'maps.pirates.structures.island_structures.roc.data'
@ -6,10 +8,7 @@ Public.shelter1 = {}
Public.shelter1.Data = Data.shelter1
Public.shelter2 = {}
Public.shelter2.Data = Data.shelter2
Public.covered1 = {}
Public.covered1.Data = Data.covered1
Public.covered1b = {}
Public.covered1b.Data = Data.covered1b
Public.lonely_storage_tank = {}
Public.lonely_storage_tank.Data = Data.lonely_storage_tank
Public.swamp_lonely_storage_tank = {}

View File

@ -0,0 +1,81 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
Public.step1 = {
name = 'furnace1_step1',
width = 14,
height = 15,
components = {
--for some reason tile blueprints need to be offset...
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = 0, y = 0},
bp_string = [[0eNqVmM1qwkAYRd9l1ink+5n8vUpxYXWQAU1CTEtF8u412kUXbfGsQuB4E7gH7phreDu+p3HK/Ry6azj32/FlHl4OU96v95+hEy/C5XaJSxHybujPoXu9gfnQb48rMl/GFLqQ53QKRei3p/Xuxu2mNKew/qjfpzVn2RRhzsf0CBiHc57z0H8/pXw8ZPkt4Q9YCWwEdgJHAlcErgncELglsJSIRh0KKlGebFHudElgIbASGL2zEzgSuCJwTeCGwC0qhVWIOhRUIjNPnqxRiadKPFXiqRJPlXiqxFMlnirxVImnSjxV5KkiTxV5qshTRZ4a8dSIp0Y8NeKpEU+NeGrEUyOeGvHUiKeGPDXkqSFPDXlqyFMn6jlRz4l6TtRzop6Tzh117qhzR5076jySFiOKrkh0haJrEl2j6IZENyi6JdEtOwqhv3QCT/js1A4PceioJWx5Be2joIEUtJCCJlLQRgoaSUErKWgmBe2ksKEUtpTCplL+28pN8fjk0v34gFOEjzSd7wHaiNet1tHFYhmX5QubhLg2]],
},
{
type = 'tiles',
tile_name = 'out-of-map',
offset = {x = 1.5, y = 0},
bp_string = [[0eNqV2EFuwjAQQNG7zDpIxJ6xTa5SsaBgIUuQREmoilDuXgJddNFW/KWl77Hkt5ubvJ8uuR9KO0lzk7Hd9aupWx2HcljOn9JsKrlKU9dzJWXftaM0b/euHNvdaSmma5+lkTLls1TS7s7L6d7thzxlWS61h3wfU8/bSqZyys8BfTeWqXTt9yPrxyM6/zbhj9hIHF6L60e8JnFNYkdiT2IlsZEYfV0kcSLxBqG8SOiItyPejng74u2ItyPejng74u2ItyPeDnl74u2Jtyfennh74u2Jtyfennh74u2Jt0feSryVeCvxVuKtxFuJtxJvJd5KvJV4K/I24m3E24i3EW8j3ka8jXgb8TbibcTbkHcg3oF4B+IdiHcg3oF4B+IdiHcg3oF4B+QdiXck3pF4R+IdiXck3pF4R+IdiXck3hF5J+KdiHci3ol4J+KdiHci3ol4J+KdiHf6x3tbPdcGzY8dRCUfeRgf912qNW5cNK29rW2evwC3J1mB]],
},
--this needs to appear last, so that the walls connect properly
{
type = 'static',
force = 'environment',
offset = {x = 0, y = 0},
bp_string = [[0eNqlmNtuozAURf/Fz1DhG7dfGVUjkngiJGoQmJlGVf59oOlDNJMdvMsTQsLrXNjn2Mcf4tDNbhhbH0T9ISbfDGno0/PYntb3d1FLk4jL8rDXRLTH3k+i/rF82J59062fhMvgRC3a4N5EInzztr5Nofcu/dN0nViX+ZNbSddkc6F7H0Y3TWnXNyc33i1W19dEOB/a0LqbC58vl59+fjssX9bykfFEDP20LOn9VzTZi72F82Kvqzv/QFQURD6H6P+imZcYxvPYL8/04LqAkYt/S8xfqennMMxBPDBhovxUz/20URD9HJJ/I1jNBVt8w4TiTJRRqTDPU1FFQexziMyiKPkGJa4aig1KXDmUGxQdV1QbapVxmpcbepUW9RpYkyZGQTKn+o8G3hU7eoe613rrkaMl5agCjlbRadRMGlUWzVUUV+7oU3GJVWpHn4o0oak+BUSmDEUBClCWq0eEyTkMiqmgVG0AhasNCygVlV9A0RlFARFpyaUXYRSHQTHdHY06dwxje0x/zaNvjg6XRgFYhvpXOaBYioJ8IUWMnCk4DPKGU3EJKBVFqR5TDKdiRCFVDEIypIqRN5o+QkgZ0d0Np2iZAfc4SUtwUDI5vcPHRVnQO3wclzzDo7C55o1+gs3I0yrikMpHYVnFiQLs1nbPbCtV3DBmyToARwJruWEeYfZMuNEh75lxo42U3K0BSkjF3RsATM7tDBAjuakbYRTnDaiPXHPTO/LGcOM7wlhufkeYnBzgEYc83kBOSXLQz6r2NDMTNbEV2Z7uEWlD7mkej2y8Jrdr2frudjgRv904fQJUKU1RqcIaqW225PYv7EY6nw==]],
},
},
}
Public.step1.red_chests = {
{x = -6, y = -2},
{x = -5, y = -2},
{x = -4, y = -2},
}
Public.step1.blue_chests = {
{x = -6, y = 2},
{x = -5, y = 2},
{x = -4, y = 2},
}
Public.step1.walls = {
{x = 2, y = -6},
{x = 3, y = -6},
{x = 4, y = -6},
{x = 2, y = 6},
{x = 3, y = 6},
{x = 4, y = 6},
}
Public.step2 = {
name = 'furnace1_step2',
width = 17,
height = 15,
doNotDestroyExistingEntities = true,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = 1.5, y = 0},
bp_string = [[0eNqV2EFuwjAQQNG7zDpIxJ6xTa5SsaBgIUuQREmoilDuXgJddNFW/KWl77Hkt5ubvJ8uuR9KO0lzk7Hd9aupWx2HcljOn9JsKrlKU9dzJWXftaM0b/euHNvdaSmma5+lkTLls1TS7s7L6d7thzxlWS61h3wfU8/bSqZyys8BfTeWqXTt9yPrxyM6/zbhj9hIHF6L60e8JnFNYkdiT2IlsZEYfV0kcSLxBqG8SOiItyPejng74u2ItyPejng74u2ItyPeDnl74u2Jtyfennh74u2Jtyfennh74u2Jt0feSryVeCvxVuKtxFuJtxJvJd5KvJV4K/I24m3E24i3EW8j3ka8jXgb8TbibcTbkHcg3oF4B+IdiHcg3oF4B+IdiHcg3oF4B+QdiXck3pF4R+IdiXck3pF4R+IdiXck3hF5J+KdiHci3ol4J+KdiHci3ol4J+KdiHf6x3tbPdcGzY8dRCUfeRgf912qNW5cNK29rW2evwC3J1mB]],
},
{
type = 'static',
force = 'ancient-friendly',
offset = {x = -1, y = 0},
bp_string = [[0eNqV01FvgyAQAOD/cs+4COpU/krTLNZeOxI9DGAz0/jfh2wPTYZdeSKX3H054O4Op2HGyShyIO9gqZsyp7OrUect/gJZMFhAcr4yUL0mC/Lg89SVumHLcMuEIEE5HIEBdeMWWYc4ZP0nWgdbHZ3RS3w9MkByyin8YUKwfNA8ntD4hCjAYNLW12j67Sh/q0JP/lxX9kcRaQqPK8VrCn+ulGnKzo2qB0UTZpfZUNdjxAlKETPe016ljndSpylNXGnSlDautGlvu6PwPHFcdv6Ivzi84j9HJA5ecPxihQ2UD+vM4IbGhgrR8LJuRV2VvKhyn/8NRt5ISg==]],
},
},
}
Public.step2.market = {x = 4, y = 0}
Public.step2.wooden_chests = {
{x = 5, y = -5},
{x = 5, y = -4},
{x = 5, y = 4},
{x = 5, y = 5},
}
return Public

View File

@ -0,0 +1,281 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
local Balance = require 'maps.pirates.balance'
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 CustomEvents = require 'maps.pirates.custom_events'
-- local SurfacesCommon = require 'maps.pirates.surfaces.common'
local Raffle = require 'maps.pirates.raffle'
local ShopCovered = require 'maps.pirates.shop.covered'
local Classes = require 'maps.pirates.roles.classes'
local Loot = require 'maps.pirates.loot'
local Public = {}
Public.Data = require 'maps.pirates.structures.quest_structures.furnace1.data'
function Public.create_step1_entities()
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local quest_structure_data = destination.dynamic_data.quest_structure_data
if not quest_structure_data then return end
local position = quest_structure_data.position
local hardcoded_data = Public.Data.step1
quest_structure_data.blue_chests = {}
for _, chest_position in pairs(hardcoded_data.blue_chests) do
local e = surface.create_entity{name = 'blue-chest', position = Math.vector_sum(position, chest_position), force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
e.operable = false
e.destructible = false
quest_structure_data.blue_chests[#quest_structure_data.blue_chests+1] = e
end
end
quest_structure_data.red_chests = {}
for _, chest_position in pairs(hardcoded_data.red_chests) do
local e = surface.create_entity{name = 'red-chest', position = Math.vector_sum(position, chest_position), force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
e.operable = false
e.destructible = false
quest_structure_data.red_chests[#quest_structure_data.red_chests+1] = e
end
end
quest_structure_data.door_walls = {}
for _, p in pairs(hardcoded_data.walls) do
local e = surface.create_entity{name = 'stone-wall', position = Math.vector_sum(position, p), force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
e.operable = false
e.destructible = false
end
quest_structure_data.door_walls[#quest_structure_data.door_walls + 1] = e
end
end
function Public.create_step2_entities()
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local quest_structure_data = destination.dynamic_data.quest_structure_data
if not quest_structure_data then return end
local position = quest_structure_data.position
local hardcoded_data = Public.Data.step2
quest_structure_data.market = surface.create_entity{name = 'market', position = Math.vector_sum(position, hardcoded_data.market), force = string.format('ancient-friendly-%03d', memory.id)}
if quest_structure_data.market and quest_structure_data.market.valid then
quest_structure_data.market.minable = false
quest_structure_data.market.rotatable = false
quest_structure_data.market.destructible = false
quest_structure_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = Balance.coin_sell_amount}}
quest_structure_data.market.add_market_item{price={{'burner-mining-drill', 1}}, offer={type = 'give-item', item = 'iron-plate', count = 9}}
local how_many_coin_offers = 4
if Balance.crew_scale() >= 1.2 then how_many_coin_offers = 5 end
local coin_offers = ShopCovered.market_generate_coin_offers(how_many_coin_offers)
for _, o in pairs(coin_offers) do
quest_structure_data.market.add_market_item(o)
end
if destination.static_params.class_for_sale then
quest_structure_data.market.add_market_item{price={{'coin', Balance.class_cost(false)}}, offer={type="nothing", effect_description = {'pirates.market_description_purchase_class', Classes.display_form(destination.static_params.class_for_sale)}}}
-- destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
-- text = 'Class available: ' .. Classes.display_form(destination.static_params.class_for_sale),
-- surface = surface,
-- target = Utils.psum{special.position, hardcoded_data.market, {x = 1, y = -3.9}},
-- color = CoreData.colors.renderingtext_green,
-- scale = 2.5,
-- font = 'default-game',
-- alignment = 'center'
-- }
end
end
for _, w in pairs(quest_structure_data.door_walls) do
if w and w.valid then
w.destructible = true
w.destroy()
end
end
quest_structure_data.wooden_chests = {}
for k, p in ipairs(hardcoded_data.wooden_chests) do
local e = surface.create_entity{name = 'wooden-chest', position = Math.vector_sum(position, p), 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)
if k==1 then
inv.insert({name = 'coin', count = 2000})
elseif k==4 then
local loot = Loot.covered_wooden_chest_loot_1()
for j = 1, #loot do
local l = loot[j]
inv.insert(l)
end
else
local loot = Loot.covered_wooden_chest_loot_2()
for j = 1, #loot do
local l = loot[j]
inv.insert(l)
end
end
end
quest_structure_data.wooden_chests[#quest_structure_data.wooden_chests + 1] = e
end
end
Public.entry_price_data_raw = {-- choose things which make interesting minifactories
['electric-mining-drill'] = {
overallWeight = 1,
minLambda = -0.75,
maxLambda = 0.75,
shape = 'bump',
enabled = true,
base_amount = 600,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 46, ['copper-plate'] = 9},
},
['fast-splitter'] = {
overallWeight = 1,
minLambda = -1,
maxLambda = 1,
shape = 'bump',
enabled = true,
base_amount = 300,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 92, ['copper-plate'] = 45},
},
['assembling-machine-1'] = {
overallWeight = 1,
minLambda = -1,
maxLambda = 1,
shape = 'bump',
enabled = true,
base_amount = 600,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 44, ['copper-plate'] = 9},
},
['filter-inserter'] = {
overallWeight = 1,
minLambda = 0,
maxLambda = 1,
shape = 'density',
enabled = true,
base_amount = 500,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 32, ['copper-plate'] = 24},
},
['programmable-speaker'] = {
overallWeight = 1,
minLambda = 0,
maxLambda = 1,
shape = 'density',
enabled = true,
base_amount = 500,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 18, ['copper-plate'] = 17},
},
['pump'] = {
overallWeight = 1,
minLambda = 0.05,
maxLambda = 1,
shape = 'density',
enabled = true,
base_amount = 350,
itemBatchSize = 1,
batchRawMaterials = {['iron-plate'] = 15},
},
['grenade'] = {
overallWeight = 1,
minLambda = 0.05,
maxLambda = 1,
shape = 'density',
enabled = true,
base_amount = 500,
itemBatchSize = 1,
batchRawMaterials = {['iron-plate'] = 5, ['coal'] = 10},
},
['assembling-machine-2'] = {
overallWeight = 1,
minLambda = 0.2,
maxLambda = 1.2,
shape = 'bump',
enabled = true,
base_amount = 300,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 160, ['copper-plate'] = 18},
},
['pumpjack'] = {
overallWeight = 1,
minLambda = 0.35,
maxLambda = 1,
shape = 'density',
enabled = true,
base_amount = 250,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 120, ['copper-plate'] = 15},
},
['oil-refinery'] = {
overallWeight = 1,
minLambda = 0.35,
maxLambda = 1,
shape = 'density',
enabled = true,
base_amount = 100,
itemBatchSize = 1,
batchRawMaterials = {['iron-plate'] = 115, ['copper-plate'] = 15, ['stone-brick'] = 10},
},
['chemical-plant'] = {
overallWeight = 1,
minLambda = 0.35,
maxLambda = 1,
shape = 'density',
enabled = true,
base_amount = 150,
itemBatchSize = 2,
batchRawMaterials = {['iron-plate'] = 90, ['copper-plate'] = 15},
},
}
function Public.entry_price()
local lambda = Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress())
local item = Raffle.LambdaRaffle(Public.entry_price_data_raw, lambda)
local batchSize = Public.entry_price_data_raw[item].itemBatchSize
return {
name = item,
count = Math.ceil(
(0.9 + 0.2 * Math.random()) * Public.entry_price_data_raw[item].base_amount * Balance.quest_structure_entry_price_scale() / batchSize
) * batchSize,
batchSize = batchSize,
batchRawMaterials = Public.entry_price_data_raw[item].batchRawMaterials,
}
end
return Public

View File

@ -0,0 +1,71 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
Public.step1 = {
name = 'market1_step1',
width = 15,
height = 18,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = 0, y = 0},
bp_string = [[0eNqVmc1Kw0AYRd9l1hHmfvOfVxEX1QYJ1LS0URTJu9u0Llyo9KxK4DaBe3oDZ/rpHnevw+E4TrPrP91p2hzu5v3d83Hcrtfvrlfq3Mf5oy6dG5/208n19+fg+Dxtdmtk/jgMrnfjPLy4zk2bl/XqnHs6DvPg1i9N22G9z/LQuXncDdcbHPancR730/dT/OUhtvx2hz/CSreldUl7EhYJGwkHEo4kjNrIJFxIuJJwQ1AYQsRQCKIQRSGM7FctBFI3kjSyGCOLMbIYI4sxshgjizGyGCOLMbIYI4sxtBhDizG0GEOLMbQYQ4sxtBhDiwlkMYEsJpDFBLKYgMgERCYgMgGRCYhMJGQiIRMJmUjIRNReRO1F1F4i7SXSXiLtJdJeQu0l1F5C7WXSXibtZdJeJu1l1F5G7WXUXiHtFdJeIe0V0l5B79SC3qkFkSmITEFkKiFTCZlKyFRCpiIyFZGpiExFZCoi0wiZRsg01F9D/TXUX0P9NdSfPDos8Oi0wDN59Mwe4aGIZ/7oWY3szIUdukAHhxIOLRxqOPNwIREXMnEhFRdycSEZF7JxIR0X8nEhIRcycjElF3NyMSkXs3IxLRfzcjExFzNzITUXcnMhORey8+90ROmE0hmlWd8VpRujA2EymmI4xXiKARUjKob05g39dyDx0F3/++l//JPUubfheLrcwKpiaVZSVEg+LcsXIxltDQ==]],
},
{
type = 'tiles',
tile_name = 'out-of-map',
offset = {x = 0, y = -1},
bp_string = [[0eNqd2D1uwkAQQOG7TG0kZn+Yta8SURBYoZXAtmwnCkK+ezCkSJFEvJQrvZkpvm6v8np6y/1Q2kmaq4ztrl9N3eo4lMPy/pCmruQijfq5krLv2lGal1tXju3utBTTpc/SSJnyWSppd+fldev2Q56yLEPtId/W6LytZCqn/FjQd2OZStd+HVnfj7j5pw2/xJ7EgcSRxBsSG4kTiWsS6/q5WomKEhUlKkpUlKgoUVGiokRF/6GiiuonER0Rd0TcEXFHxB0Rd0TcEXFHxB0Sd0jcIXFPxD0R90TcE3FPxD0R90TcE3GPxD0S90g8EPFAxAMRD0Q8EPFAxAMRD0Q8IPFIVCJRiUQlEpVIVCJRiUQlEpWIVDb3GsVKYkdiT+JA4kjiDYmNxInENUJ5ktCItxFvI95GvI14G/E24m3E24i3EW9D3ol4J+KdiHci3ol4J+KdiHci3ol4J+Kd/vDeVo9/iebbJ0cl73kY7/MuabDaWQzq4zrO8yeeGHe9]],
},
{
type = 'static',
force = 'environment',
offset = {x = 0, y = 0},
bp_string = [[0eNqlmN1uozAQhd/F16TC/5BXqaoVaawIiQICZ7dRlXdfsumuqiUHfOgVQjHfHI9nJjP+EIfmHPqhbqPYf4ixrfpd7HanoT7e3t/FXspMXKaHu2aifu3aUeyfp4X1qa2a25J46YPYizqGN5GJtnq7vY2xa8PuV9U04vZZeww30vUlE6GNdazDnfLn5fKjPb8dwjAt+Pd9eO+HMI678/TlcBq66bk7hCZOFvpunABd+ykvf7J3fU92snSsh/B6/9Vlf6V159if4yRkZlA9EjwzIb+YeADRFCR/DDFJkHwZYmf+a7pqcuAcZLb7zG04JLV+SHUL7Pkkz+hlzxRJELUMKZMgdhki8ySKWaHIJIpbjlyZFv9+RYumtCBKWgaUKxSbRClWKC4tpfMV93oOg9QUVG3QgFJSZUo9pqic0oIoksppRFFUUiOKpvIRUQxVGxDFUpmEKGT0goBRZPQiNVz0ekApOTEAo7nwLQFFUpQCUBS3JSRGcxikhmtAJOqFLIcBJU+zBRjJIWMY6uGCWIKU0lwNRhiTcxiQmYYLY4hRs4YwDlU79t0QQTto1zaotyPV/y2memTA0AYcZ8DSBjxnwFHtEvS05zAoBgp6u8Uakqz4aIc2JzlAjyWzxQIMOXIijP7OqGxmEbY+hlnDCTdAuKWaNrh/R3WQEOPZiXmT64rvjMwLFvGQbkuqq0X+cTnV1kIMOa0iDDeuQoxOPnQPjiDh2sJx8ywUyw20EEP+XYDsdX5DJBcwkpOumwqyfiMPlBukyzxB+2cIvGT3O9D9lxvVTPwMw3jP2kIaXypvrTHWu+v1N43K86A=]],
},
},
}
Public.step1.red_chest = {x = 0, y = -7}
Public.step1.blue_chest = {x = 0, y = 6}
Public.step1.walls = {
{x = -5, y = -4},
{x = -5, y = -3},
{x = -5, y = -2},
{x = 5, y = -4},
{x = 5, y = -3},
{x = 5, y = -2},
}
Public.step2 = {
name = 'market1_step2',
width = 17,
height = 15,
doNotDestroyExistingEntities = true,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = 0, y = -1},
bp_string = [[0eNqd2D1uwkAQQOG7TG0kZn+Yta8SURBYoZXAtmwnCkK+ezCkSJFEvJQrvZkpvm6v8np6y/1Q2kmaq4ztrl9N3eo4lMPy/pCmruQijfq5krLv2lGal1tXju3utBTTpc/SSJnyWSppd+fldev2Q56yLEPtId/W6LytZCqn/FjQd2OZStd+HVnfj7j5pw2/xJ7EgcSRxBsSG4kTiWsS6/q5WomKEhUlKkpUlKgoUVGiokRF/6GiiuonER0Rd0TcEXFHxB0Rd0TcEXFHxB0Sd0jcIXFPxD0R90TcE3FPxD0R90TcE3GPxD0S90g8EPFAxAMRD0Q8EPFAxAMRD0Q8IPFIVCJRiUQlEpVIVCJRiUQlEpWIVDb3GsVKYkdiT+JA4kjiDYmNxInENUJ5ktCItxFvI95GvI14G/E24m3E24i3EW9D3ol4J+KdiHci3ol4J+KdiHci3ol4J+Kd/vDeVo9/iebbJ0cl73kY7/MuabDaWQzq4zrO8yeeGHe9]],
},
{
type = 'static',
force = 'ancient-friendly',
offset = {x = 3, y = 2},
bp_string = [[0eNqdkd0KgzAMhd8l11X8xa2vMsbwJ0hB09LGoYjvvlZ3MdjYhVfhkJMvh2SFZpjQWEUMcgVHtYlYR71VXdAzyFTAAjLfBKhWkwN58zbVUz0EAy8GQYJiHEEA1WNQOBuLzkVsa3JGW44aHBgCgjoMzO0uAIkVKzyIu1geNI0N2n3pf5YAo50f1/SOmcTlHjSNy20TX8DsNNBXH7xTFtujm/3A56fxWcjrr7FfUH58Q8ATrTs2XtKiumZVWaR5mXj/CzxjkfE=]],
},
},
}
Public.step2.market = {x = 3, y = -6}
Public.step2.steel_chest = {x = 4, y = 1}
Public.step2.wooden_chests = {
{x = 0, y = -5},
{x = -4, y = -1},
{x = -4, y = 3},
}
return Public

View File

@ -0,0 +1,279 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
local Balance = require 'maps.pirates.balance'
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 CustomEvents = require 'maps.pirates.custom_events'
-- local SurfacesCommon = require 'maps.pirates.surfaces.common'
local Raffle = require 'maps.pirates.raffle'
local ShopCovered = require 'maps.pirates.shop.covered'
local Classes = require 'maps.pirates.roles.classes'
local Loot = require 'maps.pirates.loot'
local Public = {}
Public.Data = require 'maps.pirates.structures.quest_structures.market1.data'
function Public.create_step1_entities()
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local quest_structure_data = destination.dynamic_data.quest_structure_data
if not quest_structure_data then return end
local position = quest_structure_data.position
local hardcoded_data = Public.Data.step1
quest_structure_data.blue_chest = surface.create_entity{name = 'blue-chest', position = Math.vector_sum(position, hardcoded_data.blue_chest), force = 'environment'}
if quest_structure_data.blue_chest and quest_structure_data.blue_chest.valid then
quest_structure_data.blue_chest.minable = false
quest_structure_data.blue_chest.rotatable = false
quest_structure_data.blue_chest.operable = false
quest_structure_data.blue_chest.destructible = false
end
quest_structure_data.red_chest = surface.create_entity{name = 'red-chest', position = Math.vector_sum(position, hardcoded_data.red_chest), force = 'environment'}
if quest_structure_data.red_chest and quest_structure_data.red_chest.valid then
quest_structure_data.red_chest.minable = false
quest_structure_data.red_chest.rotatable = false
quest_structure_data.red_chest.operable = false
quest_structure_data.red_chest.destructible = false
end
quest_structure_data.door_walls = {}
for _, p in pairs(hardcoded_data.walls) do
local e = surface.create_entity{name = 'stone-wall', position = Math.vector_sum(position, p), force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
e.operable = false
e.destructible = false
end
quest_structure_data.door_walls[#quest_structure_data.door_walls + 1] = e
end
end
function Public.create_step2_entities()
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local quest_structure_data = destination.dynamic_data.quest_structure_data
if not quest_structure_data then return end
local position = quest_structure_data.position
local hardcoded_data = Public.Data.step2
quest_structure_data.market = surface.create_entity{name = 'market', position = Math.vector_sum(position, hardcoded_data.market), force = string.format('ancient-friendly-%03d', memory.id)}
if quest_structure_data.market and quest_structure_data.market.valid then
quest_structure_data.market.minable = false
quest_structure_data.market.rotatable = false
quest_structure_data.market.destructible = false
quest_structure_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = Balance.coin_sell_amount}}
quest_structure_data.market.add_market_item{price={{'burner-mining-drill', 1}}, offer={type = 'give-item', item = 'iron-plate', count = 9}}
local how_many_coin_offers = 4
if Balance.crew_scale() >= 1.2 then how_many_coin_offers = 5 end
local coin_offers = ShopCovered.market_generate_coin_offers(how_many_coin_offers)
for _, o in pairs(coin_offers) do
quest_structure_data.market.add_market_item(o)
end
if destination.static_params.class_for_sale then
quest_structure_data.market.add_market_item{price={{'coin', Balance.class_cost(false)}}, offer={type="nothing", effect_description = {'pirates.market_description_purchase_class', Classes.display_form(destination.static_params.class_for_sale)}}}
-- destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
-- text = 'Class available: ' .. Classes.display_form(destination.static_params.class_for_sale),
-- surface = surface,
-- target = Utils.psum{special.position, hardcoded_data.market, {x = 1, y = -3.9}},
-- color = CoreData.colors.renderingtext_green,
-- scale = 2.5,
-- font = 'default-game',
-- alignment = 'center'
-- }
end
end
quest_structure_data.steel_chest = surface.create_entity{name = 'steel-chest', position = Math.vector_sum(position, hardcoded_data.steel_chest), force = string.format('ancient-friendly-%03d', memory.id)}
if quest_structure_data.steel_chest and quest_structure_data.steel_chest.valid then
quest_structure_data.steel_chest.minable = false
quest_structure_data.steel_chest.rotatable = false
quest_structure_data.steel_chest.destructible = false
local inv = quest_structure_data.steel_chest.get_inventory(defines.inventory.chest)
local loot = destination.dynamic_data.quest_structure_data.entry_price.raw_materials
for j = 1, #loot do
local l = loot[j]
if l.count > 0 then
inv.insert(l)
end
end
end
for _, w in pairs(quest_structure_data.door_walls) do
w.destructible = true
w.destroy()
end
quest_structure_data.wooden_chests = {}
for k, p in ipairs(hardcoded_data.wooden_chests) do
local e = surface.create_entity{name = 'wooden-chest', position = Math.vector_sum(position, p), 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.covered_wooden_chest_loot()
if k==1 then loot[1] = {name = 'coin', count = 2000} end
--@TODO: log this in coin stats
for j = 1, #loot do
local l = loot[j]
inv.insert(l)
end
end
quest_structure_data.wooden_chests[#quest_structure_data.wooden_chests + 1] = e
end
end
Public.entry_price_data_raw = {
--watch out that the raw_materials chest can only hold e.g. 4.8 iron-plates
-- choose things that are easy to make at outposts
-- if the prices are too high, players will accidentally throw too much in when they can't do it
['iron-stick'] = {
overallWeight = 1,
minLambda = 0,
maxLambda = 1,
shape = false,
base_amount = 1500,
raw_materials = {{name = 'iron-plate', count = 750}}
},
['copper-cable'] = {
overallWeight = 0.85,
minLambda = 0,
maxLambda = 1,
shape = false,
base_amount = 1500,
raw_materials = {{name = 'copper-plate', count = 750}}
},
['small-electric-pole'] = {
overallWeight = 1,
minLambda = 0,
maxLambda = 0.3,
shape = false,
base_amount = 450,
raw_materials = {{name = 'copper-plate', count = 900}}
},
['assembling-machine-1'] = {
overallWeight = 1,
minLambda = 0.1,
maxLambda = 1,
shape = false,
base_amount = 80,
raw_materials = {{name = 'iron-plate', count = 1760}, {name = 'copper-plate', count = 360}}
},
['burner-mining-drill'] = {
overallWeight = 0.25,
minLambda = 0,
maxLambda = 0.15,
shape = false,
base_amount = 150,
raw_materials = {{name = 'iron-plate', count = 1350}}
},
['burner-inserter'] = {
overallWeight = 0.75,
minLambda = 0,
maxLambda = 0.6,
shape = false,
base_amount = 300,
raw_materials = {{name = 'iron-plate', count = 900}}
},
['small-lamp'] = {
overallWeight = 1,
minLambda = 0.05,
maxLambda = 0.7,
shape = false,
base_amount = 300,
raw_materials = {{name = 'iron-plate', count = 600}, {name = 'copper-plate', count = 900}}
},
['firearm-magazine'] = {
overallWeight = 1,
minLambda = 0,
maxLambda = 1,
shape = false,
base_amount = 700,
raw_materials = {{name = 'iron-plate', count = 2800}}
},
['constant-combinator'] = {
overallWeight = 0.6,
minLambda = 0,
maxLambda = 1,
shape = false,
base_amount = 276,
raw_materials = {{name = 'iron-plate', count = 552}, {name = 'copper-plate', count = 1518}}
},
['stone-furnace'] = {
overallWeight = 1,
minLambda = 0.05,
maxLambda = 1,
shape = false,
base_amount = 250,
raw_materials = {{name = 'stone', count = 1250}}
},
['advanced-circuit'] = {
overallWeight = 1,
minLambda = 0.4,
maxLambda = 1.6,
shape = true,
base_amount = 180,
raw_materials = {{name = 'iron-plate', count = 360}, {name = 'copper-plate', count = 900}, {name = 'plastic-bar', count = 360}}
},
['wooden-chest'] = {
overallWeight = 0.5,
minLambda = -0.5,
maxLambda = 0.5,
shape = true,
base_amount = 400,
raw_materials = {}
},
['iron-chest'] = {
overallWeight = 0.5,
minLambda = 0,
maxLambda = 1,
shape = true,
base_amount = 250,
raw_materials = {{name = 'iron-plate', count = 2000}}
},
['steel-chest'] = {
overallWeight = 0.5,
minLambda = 0.25,
maxLambda = 1.75,
shape = true,
base_amount = 125,
raw_materials = {{name = 'steel-plate', count = 1000}}
},
}
function Public.entry_price()
local lambda = Math.clamp(0, 1, Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress())
local item = Raffle.LambdaRaffle(Public.entry_price_data_raw, lambda)
local raw_materials = Public.entry_price_data_raw[item].raw_materials
return {
name = item,
count = Math.ceil(
(0.9 + 0.2 * Math.random()) * Public.entry_price_data_raw[item].base_amount * Balance.quest_structure_entry_price_scale()
),
raw_materials = raw_materials,
}
end
return Public

View File

@ -0,0 +1,158 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Public = {}
Public.covered1 = {
name = 'covered1',
width = 17,
height = 15,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = -9, y = -8},
bp_string = [[0eNqVmMGKwjAURf8l6wreJG2S/srgwtEgAW1L7Qwj0n8fqy5m4YBnJcKxHrxc7sOr+Tx+5WEs3WTaqzl322E19avDWPbL+x/TKlXmcnsJc2XKru/Opv24geXQbY8LMl2GbFpTpnwylem2p+XdjduNecpm+VC3z8tz5k1lpnLMjwcM/blMpe+e37K+f8l6fvWEf2AR2BLYEdgTuCZwQ+BA4EjghEJhEaIMhUIUSlEoRqEc9WaQIh0Q6YBIB0Q6INIBkQ6IdECkAyIdEOmAUAeEOiDUAaEOCHVAqANCHbCkA5Z0wCJri6wdsXbE2iFrh6w9sfbE2iNrj6xrYl0T6xpZ18i6IdYNsW6QdYOsA7EOxDog64CsI7GOxDoi64isE7FOxDoh68RuFnS4C13uYseW4LXFzi12b8GJZBspNJJCKyk2k2I7KTSUQkspNpViWyk0lkJrKTaXYnspNJhCiyk2mWKbKTSaQqspNptiuyk0nELL+aQtoh2iPaJrRLNfMCA6IjqxdGCYLE2xOMXyFAtULNG3S4HuMqHD7ElbRDtEe0TXiGa/YEB0RHRi6cAwWZpicYrlKRaoWKKvS7GpHv+Tt3/+da/Mdx7P9wfYKB+SDd41Ptk4z7+pVIVy]],
},
{
type = 'tiles',
tile_name = 'green-refined-concrete',
offset = {x = -1, y = 2},
bp_string = [[0eNqV0tsKwjAMBuB3yXWF9bCDfRXxYm5lFLa2tFUco+9uO70QVDCXgS9/CMkGl/mqnNcmgtwgmN4doj1MXo+lvoNsCawg60RAD9YEkKfM9GT6uYC4OgUSdFQLEDD9UqrsBq+igtJkRpVTaDoTiHpWzwBng47amteMap8h0reED0wxmGEw33GFwRSDGQZzDP5zQYHBNQY3v3E+/P4e8u3VCNyUD3s766hoj6wVjPOublJ6AP6T06c=]],
},
{
type = 'tiles',
tile_name = 'out-of-map',
offset = {x = -7, y = -6},
bp_string = [[0eNqd2s1Kw0AUhuF7mXWEfnPO/OVWxEXVIIGaljaKIrl3G3XhQqWvqxA4nUDOs3qbt3C7exoOx3GaQ/8WTtP2cDXvrx6O4/16/xJ6pS68ni+2dGG820+n0F+fB8eHabtbR+bXwxD6MM7DY+jCtH1c785zd8dhHsL6o+l+WM9Zbrowj7vh84DD/jTO4376esrm4yGb5acTfhkWGY5k2Miwk+FEhjMZLmS4kuGGlsJWiHaoC5coYknEkoglEUsilkQsiVgSsSRiScSSkCUhS0KWIrEUiaVILEViKRJLkViKxFIkliKxFImliCxFZCkiS0YsGbFkxJIRS0YsGbFkxJIRS0YsGbFkyJIhS4YsObHkxJITS04sObHkxJITS04sObHkxJIjS44sObKUiKVELCViKRFLiVhKxFIilhKxlIilRCwlZCkhSwlZysRSJpYysZSJpUwsZWIpE0uZWMrEUiaWMrKUkaVCdBSioxAdhegoREchOgrRUYiOQnQUoqMgHQXpqERHJToq0VGJjkp0VKKjEh2V6KhERyU6KtJRkY5GdDSioxEdjehoREcjOhrR0VDVQSlWqMUKxVihGiuUY4V6rFCQ1eYf77ui6ca2A5d56TZZaGWllaVW1lpZbGW1leVW1ltZcGXFFSZX2FxRRhXqqEIhVaikCqVUoZYqFFOFaqpQThXqqWJBVayoCkVSoUoqlEmFOqlQKBUqpUKpVKiVCsVSoVoqlktl/5Fy8Z+CqJgKJVOhZioUTYWqqVA2FeqmQuFUqJwKpVOxdioWT/VXPb3pPr906L99N9GF5+F4+jggVnlpsbhlb7Euyzuk5qn3]],
},
{
type = 'static',
force = 'environment',
offset = {x = 0, y = 0},
bp_string = [[0eNqlmNtuozAQht/F11Ax+IR5lVW1Io0VIRGDwOw2qnj3hbKHSGVghr2KUODz2Hwe+PkQl2b0XV+HKMoPMYSqS2Ob3vr6uhy/ixJsIh7zj54SUb+1YRDlt/nE+haqZjklPjovSlFHfxeJCNV9ORpiG3z6s2oasVwWrn4hTa+J8CHWsfYr5fPg8T2M94vv5xO2rk9E1w7zJW34XVD2oteKXvQ0JV8gOQuSbUMkCQL7EEWC5PsQTYLIfYghQdQ+xJIgeh9SkCBmH+JIELsPgYxEKQ4oNGfdAeWftP696/0wpOO8Z/pb386/6cU3ccO+Z4eTP/uwHWM3RrE1CFHqA6uBpjUceA00seHAbKCpDQduA01uOLAbaHqD2W9h4HgYpJo8Y7VCjVCAVwyG4fVli1Aki2IQiuJNCStG8zBYNYY1J4dQLItSIJTifxqRe25EdUD6UM60G5mwzHgYZMaS+dKBbFnJ0xuw9w75Zf2btppvwM6qA1C6v2Q6j06UKT06U571y+NkE2NPCPsXKj+Fvda9f1v/zo/1lWe2iCWMuHPvHNkKd35iKqO7lyPDGMIwcKbFSHQBDWEBVc6UFrFNyTO1G0Lt+HIp3j5RSOWalWhQjGFlGhRjWakGxRSsXINiHCvZYBidsbINigFWukExOSveoBjJyjcohvj0OdJYa16GQTmGF2JQjuWlGJRT8GIMynG8HINxDPPlauW8JutnoPLpo1Iifvh+WJ9BBSjrcqukUS4vpukXJhD2Zw==]],
},
},
}
Public.covered1.red_chest = {x = 2, y = 5}
Public.covered1.blue_chest = {x = 2, y = 6}
Public.covered1.walls = {
{x = -8, y = -5},
{x = -8, y = -4},
{x = -8, y = -3},
{x = 8, y = -5},
{x = 8, y = -4},
{x = 8, y = -3},
}
Public.covered1b = {
name = 'covered1b',
width = 17,
height = 15,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = -7, y = -6},
bp_string = [[0eNqVmM1qg0AURt9l1gby3ev/q5QsbDMUwaiobROC797YlpJFaXtWInwzzmHO4rtew2P3Esep7ZdQX8PcN+NuGXbPU3vc3s+hVpaEy+3haxLap6GfQ/1wC7bPfdNtkeUyxlCHdomnkIS+OW1v8zL0cffWdF3YlvXHuO20Jn8ujOdxivO864bmGKe7xbYekrC0Xfz8/jjM7dIO/dch9x9n3K/f+9wO+jTFJYbtmz+GRcJGwk7CKQlnJJyTcEHCJQlX6FLYFaI71D8vUcQlEZdEXBJxScQlEZdEXBJxScQlEZeEXBJyScglIy4ZccmIS0ZcMuKSEZeMuGTEJSMuGXHJkEuGXDLkkhOXnLjkxCUnLjlxyYlLTlxy4pITl5y45MglRy45ciklLqXEpZS4lBKXUuJSRgAzApgRwIwAZgQwJ4A5AcwJYE4AcwJYEMCCABYEsCCABQEsCWBJAEsCWBLAkgBWBLAigBUBrAhghYo0GjuF5k6hwVNo8hQaPcUGIjYRsZGIzURsKEJVXairC5V1obYuVNeFSqRQixSqkUI9UqhICtUboX4jVHCEGo5+qTiH5PNPWX33wy4Jr3GaP9ZbqbSorEjNvczydX0HDBNakQ==]],
},
{
type = 'static',
force = 'ancient-friendly',
offset = {x = 0, y = 0},
bp_string = [[0eNqV1e9qwyAQAPB3uc+mRBOjyauMMdJFipBqiHZrKL77YsqgjPnvUzi4+0W543zAeb6JZZXKwvAAo8alsrq6rHLy8R0GTBFs+6dxCOSnVgaGtz1RXtQ4+xS7LQIGkFZcAYEarz4yVitRfY/zDL5MTcJLDiULxX1ZhTHVrMdJrC/FxL0jEMpKK8XzCEewfajb9bxnDvi/nyNYtNlLtPq9zel5nfpEnT/OH4RkIXUcabKQJo60WQiJIzQLYXGky0L6OMKyEB5HeF6LEz3u85REk3GdxyQ6hDPHNjEtOG9wcZtgmqL5bwNKW6R0AYUWKTSgdEUKDyisSGEBhRcpONSkvojpA5uuLjsMCTC4jMGe2Tf5sfWHl8cHwZdYzVFBOG5ZT1hLmobTzrkfNM8jsg==]],
},
},
}
Public.covered1b.market = {x = -2, y = -5}
Public.covered1b.steel_chest = {x = 1, y = -5}
Public.covered1b.wooden_chests = {
{x = -5, y = 1},
{x = -4, y = 3},
{x = -5, y = 5},
}
Public.covered2 = {
name = 'covered2',
width = 17,
height = 15,
components = {
--for some reason tile blueprints need to be offset...
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = -9, y = -8},
bp_string = [[0eNqVmMGKwjAURf8l6wreJG2S/srgwtEgAW1L7Qwj0n8fqy5m4YBnJcKxHrxc7sOr+Tx+5WEs3WTaqzl322E19avDWPbL+x/TKlXmcnsJc2XKru/Opv24geXQbY8LMl2GbFpTpnwylem2p+XdjduNecpm+VC3z8tz5k1lpnLMjwcM/blMpe+e37K+f8l6fvWEf2AR2BLYEdgTuCZwQ+BA4EjghEJhEaIMhUIUSlEoRqEc9WaQIh0Q6YBIB0Q6INIBkQ6IdECkAyIdEOmAUAeEOiDUAaEOCHVAqANCHbCkA5Z0wCJri6wdsXbE2iFrh6w9sfbE2iNrj6xrYl0T6xpZ18i6IdYNsW6QdYOsA7EOxDog64CsI7GOxDoi64isE7FOxDoh68RuFnS4C13uYseW4LXFzi12b8GJZBspNJJCKyk2k2I7KTSUQkspNpViWyk0lkJrKTaXYnspNJhCiyk2mWKbKTSaQqspNptiuyk0nELL+aQtoh2iPaJrRLNfMCA6IjqxdGCYLE2xOMXyFAtULNG3S4HuMqHD7ElbRDtEe0TXiGa/YEB0RHRi6cAwWZpicYrlKRaoWKKvS7GpHv+Tt3/+da/Mdx7P9wfYKB+SDd41Ptk4z7+pVIVy]],
},
{
type = 'tiles',
tile_name = 'green-refined-concrete',
offset = {x = -4, y = 2},
bp_string = [[0eNqV1NEKgjAUxvF3OdcLnO6k7lWiC9MhA52iKxLZuzeti6CCvsvBb+fwv9hWunRXM07WedIrza4aD344tJNttvOddCloIc1BkK0HN5M+RWZbV3Ub8MtoSJP1pidBruq3U3T1ZLyh7ZJrTJwiw1mQt515DhiH2Xo7uNeOZN+hwrcJH1giOEVwtuMEwRLBKYIzBP8ZqJBAhQQqJFAhgQoJZCSQkUBGAhkJZCTwiOAcwcVvHJ/u/sD122ch6Gameb+eFlLlZZqzkhknHMIDrYdkGw==]],
},
{
type = 'tiles',
tile_name = 'out-of-map',
offset = {x = -7, y = -6},
bp_string = [[0eNqd2c1qwkAYheF7mXUKnpn55ie3UrqwGiSgUTQtLZJ7r9EWurDg21URvqZw8mz6enav27fucOyH0bVndxqWh6dx/7Q59uv584drZY37vPwIU+P61X44ufb5cthvhuV2Phk/D51rXT92O9e4YbmbP13uVsdu7Nz8S8O6m58zvTRu7Lfd7QGH/akf+/3w/VcW1z+ymO494Y9jkWNPjgM5juTYyHEix5kcF3Jc0UthrxC9Qz34EkUsiVgSsSRiScSSiCURSyKWRCyJWBKyJGRJyJInljyx5IklTyx5YskTS55Y8sSSJ5Y8seSRJY8seWQpEEuBWArEUiCWArEUiKVALAViKRBLgVgKyFJAlgKyFImlSCxFYikSS5FYisRSJJYisRSJpUgsRWQpIktGdBjRYUSHER1GdBjRYUSHER1GdBjRYUiHIR2J6EhERyI6EtGRiI5EdCSiIxEdmeycyc6Z7JzJzpnsnMnOmeycyc6F7FzIzoXsXMjOhexcyM6F7FzIzpXsXMnOlexcyc6V7FzJzpXsXPnOhRxX9FLYK3z0/2qU8IQanlDEE6p4QhlPqOMJhTyhkieU8oRanljME6t5YoGOFTqW6FijY5GOVTqW6VinY6GOlTqY6vQfKQ+HX1TrhHKdUK8TCnZCxU4o2Qk1O6FoJ1TthLKdWLcTC3di5U4o3Qm1O6F4J1TvhPKdUL8TCnhCBU8o4Qk1PLGIJ1bxxDKeUMcTCnlCJU8o5Qm1PKGYJ1TzhHKeUM8TCnpiRU8s6f2c332dL83t+/f217f5jXvvjqfrA3xRzNVniwq2sGn6ArBHNd4=]],
},
--this needs to appear last, so that the walls connect properly
{
type = 'static',
force = 'environment',
offset = {x = 0, y = 0},
bp_string = [[0eNqlmNFuqzAMht8l1zBhQkjCq0zVEV2jCokGBGFbNfXdD7TaTnVWE5teVajw5Xfi38Z8iX07uX5ofBDVlxh93aehS49Dc1iuP0UFOhHn+UddEtG8dX4U1et8Y3P0dbvcEs69E5VogjuJRPj6tFyNofMu/ajbViyP+YNbSJck+qD77Ac3jmnb1Qc33D2cX3aJcD40oXE3CdeL8x8/nfbznRU8WjwRfTfOj3T+O5oXdQ0ne1GXRc5/kJwEydYhkgSR65CCBMnXIYoEUeuQkgQp1iH61wlP87kOx6Gbf9O9a8NvpL5DJt/p0k2hn4J4sIQh6SzXddoNOg1PJ2Qb1rDMNYhuiGQy0PwAEVcBzREQsQTQPAERUwDNFRCxBdB8ARFjgKZhInkLhlW5coRiWRRAimjGCwkRkwMPg6nh1XSDUCSLohFKwQsJE6N4GExNyTttrGdqFsYiFIO9A6B9AYBSCnP7ROux9+W28cgSMiNrNyztEshgywPnT/Qg4qbIJ1opcQmmnbAMlkw/ISksmX5C6p7k+QmQuicNc3MwOZbJQfQUGesFfembDzHA2x0Ms8UAP1B5Tc9DM7i32995PFkL3liACucNBihGbYhfEeLHa05RsqYRVLlmzSMohtFvnjh0mnl0RKzKWLMNiqG3k2VIeRh0GQ9a0d64bEwtzTAmhik2ZPrPRLO2AXiqK8Wbm1DtJW+MQzmaN4ChHMObwFCO5Y1gGKfMeDMYyuGOGhhnS1f5R42bbZfcvpdVd5/tEvHuhvFWkQwU2uZaFSBVNkv8C+RQcGE=]],
},
},
}
Public.covered2.red_chests = {
{x = -1, y = 5},
{x = 0, y = 5},
{x = 1, y = 5},
}
Public.covered2.blue_chest = {x = 0, y = 6}
Public.covered2.walls = {
{x = -8, y = -4},
{x = -8, y = -3},
{x = -8, y = -2},
{x = -8, y = -1},
{x = 8, y = -4},
{x = 8, y = -3},
{x = 8, y = -2},
{x = 8, y = -1},
}
Public.covered2b = {
name = 'covered2b',
width = 17,
height = 15,
doNotDestroyExistingEntities = true,
components = {
{
type = 'tiles',
tile_name = 'orange-refined-concrete',
offset = {x = -7, y = -6},
bp_string = [[0eNqV2M1qg0AYheF7+dYGcubHUW+ldJEmQxhIVIwtDcF7b0y76KItfZfCcYRn9To3ezm95nEq/WzdzS79btzMw+Y4lcP6/G6dYmVX6+qlsrIf+ot1T/ddOfa707qYr2O2zsqcz1ZZvzuvT/fdfspztvWl/pDXY5bnyuZyyp8HjMOlzGXovz6yfXxju/x0wi9jkbEjY0/GgYzj/8YiGiIaIhoiGiIaIhqOaDii4YiGIxqOaDii4YmGJxqeaHii4YmGJxqBaASiEYhGIBqBaASiEYlGJBqRaESiEYlGJBo10aiJRk00aqJRE42aaCSikYhGIhqJaCSikYhGQzQaotEQjYZoNESjIRot0WiJRks0WqLREo0W1ReKUaEaFcpRoR4VClKxImVJypqURSmrUpalqEuFwlSoTIXSVKhNheJUqE6F8lSoT4UCVahQhRJVqFGFIlWoUoUyVahThUJVf5Tq/c//cT/QfbtsqOwtT5fH+65RSK1LMcjHbVyWD41XTnY=]],
},
{
type = 'static',
force = 'ancient-friendly',
offset = {x = 0, y = -6},
bp_string = [[0eNqN01GLgzAMAOD/kuc6rNqp/SvHOPQWRkFTsd3tZPjf1+o9DO6oeQqB5CO0yRP64Y7TbMiDfoKjbsq8zW6zucb8B7RUApYQVgHmy5ID/RHqzI26IVb4ZULQYDyOIIC6MWbOW8Ls0Q0DxDa6YoTWiwAkb7zBXdmS5ZPuY49zKPivX8BkXWix9DtPftoHCnFdxR+kYCEyjZQs5JxGKhai0ohiIU0aObOQOo3UvIc9+J6GpbRppOWNUqQVmfOYg12RvLWV5QHDXNzqnQkHtR2efrtiAd84u62jaGRVt0WtKlmqPNS/ABFaQ/0=]],
},
},
}
Public.covered2b.market = {x = -4, y = -5}
Public.covered2b.wooden_chests = {
{x = -7, y = -5},
{x = -6, y = -5},
{x = 6, y = -5},
{x = 7, y = -5},
}
return Public

View File

@ -0,0 +1,401 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
-- local Balance = require 'maps.pirates.balance'
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 CustomEvents = require 'maps.pirates.custom_events'
local IslandsCommon = require 'maps.pirates.surfaces.islands.common'
-- local Raffle = require 'maps.pirates.raffle'
-- local ShopCovered = require 'maps.pirates.shop.covered'
-- local Classes = require 'maps.pirates.roles.classes'
-- local Loot = require 'maps.pirates.loot'
local Public = {}
local enum = {
MARKET1 = 'market1',
FURNACE1 = 'furnace1',
}
Public.enum = enum
Public[enum.MARKET1] = require 'maps.pirates.structures.quest_structures.market1.market1'
Public[enum.FURNACE1] = require 'maps.pirates.structures.quest_structures.furnace1.furnace1'
function Public.choose_quest_structure_type()
local destination = Common.current_destination()
local subtype = destination.subtype
local rng = Math.random(3)
if rng == 1 or subtype and subtype == IslandsCommon.enum.WALKWAYS then
return enum.MARKET1
else
return enum.FURNACE1
end
end
function Public.initialise_cached_quest_structure(position, quest_structure_type)
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
if quest_structure_type == enum.MARKET1 then
local structurePath = Public[enum.MARKET1]
local structureData = structurePath.Data.step1
local entry_price = structurePath.entry_price()
local special = Utils.deepcopy(structureData)
special.position = position
if not destination.dynamic_data.structures_waiting_to_be_placed then
destination.dynamic_data.structures_waiting_to_be_placed = {}
end
destination.dynamic_data.structures_waiting_to_be_placed[#destination.dynamic_data.structures_waiting_to_be_placed + 1] = {data = special, tick = game.tick}
local rendering1 = rendering.draw_text{
surface = surface,
target = {x = position.x + 2.65, y = position.y - 1.3},
color = CoreData.colors.renderingtext_green,
scale = 1.5,
font = 'default-game',
alignment = 'right',
}
local rendering2 = rendering.draw_sprite{
sprite = 'item/' .. entry_price.name,
surface = surface,
target = {x = position.x + 3.5, y = position.y - 0.65},
x_scale = 1.5,
y_scale = 1.5
}
local rendering3 = rendering.draw_text{
surface = surface,
target = {x = position.x + 0.5, y = position.y + 1.05},
color = CoreData.colors.renderingtext_green,
scale = 1,
font = 'default-game',
alignment = 'center',
text = {'pirates.quest_structure_market_2'},
}
local rendering4 = rendering.draw_text{
surface = surface,
target = {x = position.x + 0.5, y = position.y + 1.7},
color = CoreData.colors.renderingtext_green,
scale = 1,
font = 'default-game',
alignment = 'center',
text = {'pirates.quest_structure_market_3'},
}
destination.dynamic_data.quest_structure_data = {
quest_structure_type = quest_structure_type,
position = position,
state = 'covered',
entry_price = entry_price,
rendering1 = rendering1,
rendering2 = rendering2,
rendering3 = rendering3,
rendering4 = rendering4,
}
elseif quest_structure_type == enum.FURNACE1 then
local structurePath = Public[enum.FURNACE1]
local structureData = structurePath.Data.step1
local entry_price = structurePath.entry_price()
local special = Utils.deepcopy(structureData)
special.position = position
if not destination.dynamic_data.structures_waiting_to_be_placed then
destination.dynamic_data.structures_waiting_to_be_placed = {}
end
destination.dynamic_data.structures_waiting_to_be_placed[#destination.dynamic_data.structures_waiting_to_be_placed + 1] = {data = special, tick = game.tick}
local rendering0 = rendering.draw_text{
surface = surface,
target = {x = position.x + 2.15, y = position.y - 2.35},
color = CoreData.colors.renderingtext_green,
scale = 1.5,
font = 'default-game',
alignment = 'center',
text = {'pirates.quest_structure_furnace_1'},
}
local rendering1 = rendering.draw_text{
surface = surface,
target = {x = position.x + 2.3, y = position.y - 1.15},
color = CoreData.colors.renderingtext_green,
scale = 1.5,
font = 'default-game',
alignment = 'right',
}
local rendering2 = rendering.draw_sprite{
sprite = 'item/' .. entry_price.name,
surface = surface,
target = {x = position.x + 3.15, y = position.y - 0.5},
x_scale = 1.5,
y_scale = 1.5
}
local rendering3 = rendering.draw_text{
surface = surface,
target = {x = position.x + 2.15, y = position.y + 1.7},
color = CoreData.colors.renderingtext_green,
scale = 1,
font = 'default-game',
alignment = 'center',
text = {'pirates.quest_structure_furnace_2'},
}
local rendering4 = rendering.draw_text{
surface = surface,
target = {x = position.x + 2.15, y = position.y + 2.35},
color = CoreData.colors.renderingtext_green,
scale = 1,
font = 'default-game',
alignment = 'center',
text = {'pirates.quest_structure_furnace_3'},
}
local rendering5 = rendering.draw_text{
surface = surface,
target = {x = position.x + 2.15, y = position.y + 3.0},
color = CoreData.colors.renderingtext_green,
scale = 1,
font = 'default-game',
alignment = 'center',
text = {'pirates.quest_structure_furnace_4'},
}
destination.dynamic_data.quest_structure_data = {
quest_structure_type = quest_structure_type,
position = position,
state = 'covered',
rendering0 = rendering0,
rendering1 = rendering1,
rendering2 = rendering2,
rendering3 = rendering3,
rendering4 = rendering4,
rendering5 = rendering5,
entry_price = entry_price,
completion_counter = 0,
}
end
log('quest structure position: ' .. position.x .. ', ' .. position.y)
end
function Public.create_quest_structure_entities(name)
if name == enum.MARKET1 .. '_step1' then
local structurePath = Public[enum.MARKET1]
structurePath.create_step1_entities()
elseif name == enum.MARKET1 .. '_step2' then
local structurePath = Public[enum.MARKET1]
structurePath.create_step2_entities()
elseif name == enum.FURNACE1 .. '_step1' then
local structurePath = Public[enum.FURNACE1]
structurePath.create_step1_entities()
elseif name == enum.FURNACE1 .. '_step2' then
local structurePath = Public[enum.FURNACE1]
structurePath.create_step2_entities()
end
end
function Public.tick_quest_structure_entry_price_check()
-- function Public.tick_quest_structure_entry_price_check(tickinterval)
local memory = Memory.get_crew_memory()
if memory.game_lost then return end
local destination = Common.current_destination()
if not (destination and destination.dynamic_data) then return end
local quest_structure_data = destination.dynamic_data.quest_structure_data
if not quest_structure_data then return end
if quest_structure_data.quest_structure_type == enum.MARKET1 then
local blue_chest = quest_structure_data.blue_chest
local red_chest = quest_structure_data.red_chest
if not (blue_chest and blue_chest.valid and red_chest and red_chest.valid) then return end
local blue_inv = quest_structure_data.blue_chest.get_inventory(defines.inventory.chest)
local red_inv = quest_structure_data.red_chest.get_inventory(defines.inventory.chest)
local blue_contents = blue_inv.get_contents()
local entry_price = quest_structure_data.entry_price
local got = 0
for k, v in pairs(blue_contents) do
if quest_structure_data.state == 'covered' and k == entry_price.name then
got = v
else
-- @FIX: power armor loses components, items lose health!
red_inv.insert({name = k, count = v});
blue_inv.remove({name = k, count = v});
end
end
if quest_structure_data.state == 'covered' then
if got >= entry_price.count then
blue_inv.remove({name = entry_price.name, count = entry_price.count});
quest_structure_data.state = 'uncovered'
rendering.destroy(quest_structure_data.rendering1)
rendering.destroy(quest_structure_data.rendering2)
rendering.destroy(quest_structure_data.rendering3)
rendering.destroy(quest_structure_data.rendering4)
local special = Utils.deepcopy(Public[enum.MARKET1].Data.step2)
special.position = quest_structure_data.position
destination.dynamic_data.structures_waiting_to_be_placed[#destination.dynamic_data.structures_waiting_to_be_placed + 1] = {data = special, tick = game.tick}
else
if quest_structure_data.rendering1 then
rendering.set_text(quest_structure_data.rendering1, {'pirates.quest_structure_market_1', entry_price.count - got})
end
end
end
elseif quest_structure_data.quest_structure_type == enum.FURNACE1 then
local blue_chests = quest_structure_data.blue_chests
local red_chests = quest_structure_data.red_chests
if not (blue_chests and blue_chests[1] and blue_chests[1].valid and blue_chests[2] and blue_chests[2].valid and blue_chests[3] and blue_chests[3].valid and red_chests and red_chests[1] and red_chests[1].valid and red_chests[2] and red_chests[2].valid and red_chests[3] and red_chests[3].valid) then return end
local blue_invs = {}
blue_invs[1] = quest_structure_data.blue_chests[1].get_inventory(defines.inventory.chest)
blue_invs[2] = quest_structure_data.blue_chests[2].get_inventory(defines.inventory.chest)
blue_invs[3] = quest_structure_data.blue_chests[3].get_inventory(defines.inventory.chest)
local red_invs = {}
red_invs[1] = quest_structure_data.red_chests[1].get_inventory(defines.inventory.chest)
red_invs[2] = quest_structure_data.red_chests[2].get_inventory(defines.inventory.chest)
red_invs[3] = quest_structure_data.red_chests[3].get_inventory(defines.inventory.chest)
local blue_contents = {}
blue_contents[1] = blue_invs[1].get_contents()
blue_contents[2] = blue_invs[2].get_contents()
blue_contents[3] = blue_invs[3].get_contents()
local entry_price = quest_structure_data.entry_price --fields {name, count, batchSize, batchRawMaterials}
if quest_structure_data.state == 'covered' then
local removed = 0
local available = {0, 0, 0}
for i = 1, 3 do
local contents = blue_contents[i]
for k, v in pairs(contents) do
if k == entry_price.name then
available[i] = available[i] + v
else
blue_invs[i].remove({name = k, count = v});
red_invs[i].insert({name = k, count = v});
end
end
end
for i = 1, 3 do
local to_remove_1 = Math.min(available[i] - (available[i] % entry_price.batchSize), entry_price.count - quest_structure_data.completion_counter)
if to_remove_1 > 0 then
blue_invs[i].remove({name = entry_price.name, count = to_remove_1});
available[i] = available[i] - to_remove_1
removed = removed + to_remove_1
end
if (available[i] + (available[i-1] or 0) + (available[i-2] or 0)) >= entry_price.batchSize then --remove one more batch
local counter = entry_price.batchSize
if available[i-1] and available[i-1] > 0 then
blue_invs[i-1].remove({name = entry_price.name, count = available[i-1]});
available[i-1] = 0
counter = counter - available[i-1]
end
if available[i-2] and available[i-2] > 0 then
blue_invs[i-2].remove({name = entry_price.name, count = available[i-2]});
available[i-2] = 0
counter = counter - available[i-2]
end
blue_invs[i].remove({name = entry_price.name, count = counter});
removed = removed + entry_price.batchSize
end
end
if removed > 0 then
quest_structure_data.completion_counter = quest_structure_data.completion_counter + removed
local count = 1
for k, v in pairs(entry_price.batchRawMaterials) do
red_invs[count].insert({name = k, count = v * removed / entry_price.batchSize});
count = count + 1
end
end
if quest_structure_data.completion_counter >= entry_price.count then
quest_structure_data.state = 'uncovered'
rendering.destroy(quest_structure_data.rendering0)
rendering.destroy(quest_structure_data.rendering1)
rendering.destroy(quest_structure_data.rendering2)
rendering.destroy(quest_structure_data.rendering3)
rendering.destroy(quest_structure_data.rendering4)
rendering.destroy(quest_structure_data.rendering5)
local special = Utils.deepcopy(Public[enum.FURNACE1].Data.step2)
special.position = quest_structure_data.position
destination.dynamic_data.structures_waiting_to_be_placed[#destination.dynamic_data.structures_waiting_to_be_placed + 1] = {data = special, tick = game.tick}
else
if quest_structure_data.rendering1 then
rendering.set_text(quest_structure_data.rendering1, entry_price.count - quest_structure_data.completion_counter .. ' x')
end
end
else
local removed = 0
for i = 1, 3 do
local contents = blue_contents[i]
for k, v in pairs(contents) do
if k == entry_price.name then
blue_invs[i].remove({name = k, count = v});
removed = removed + v
else
blue_invs[i].remove({name = k, count = v});
red_invs[i].insert({name = k, count = v});
end
end
end
if removed > 0 then
local count = 1
for k, v in pairs(entry_price.batchRawMaterials) do
red_invs[count].insert({name = k, count = v * removed / entry_price.batchSize});
count = count + 1
end
end
end
end
end
return Public

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -7,6 +9,7 @@ local Loot = require 'maps.pirates.loot'
-- local Utils = require 'maps.pirates.utils_local'
local _inspect = require 'utils.inspect'.inspect
--@add stuff from new quest structures to this file?
local Public = {}
local enum = {
BOATS = 'Boats',
@ -17,7 +20,7 @@ Public[enum.BOATS] = require 'maps.pirates.structures.boats.boats'
Public[enum.ISLANDSTRUCTURES] = require 'maps.pirates.structures.island_structures.island_structures'
function Public.post_creation_process(special_name, components)
function Public.configure_structure_entities(special_name, components)
local memory = Memory.get_crew_memory()
for _, c in pairs(components) do

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Math = require 'maps.pirates.math'
@ -97,7 +99,7 @@ Public.Data.surfacename_rendering_pos = {x = -0.5, y = -15}
Public.cabin_shop_data = {
{
price = {{'coin', 300}, {'coal', 25}},
price = {{'coin', 400}, {'coal', 20}, {'iron-plate', 10}},--should be inefficient on resources to merely buy arty to shoot nests
offer = {type='give-item', item = 'artillery-shell', count = 5},
},
{
@ -108,10 +110,11 @@ Public.cabin_shop_data = {
price = {{'coin', 2000}, {'stone-brick', 30}},
offer = {type='give-item', item = 'uranium-238', count = 10},
},
{
price = {{'coin', 25}},
offer = {type='nothing', effect_description='Relax at sea for an extra minute: Increase the next destination\'s loading time by 60 seconds.'},
},
--disabled now that we can wait after any destination:
-- {
-- price = {{'coin', 25}},
-- offer = {type='nothing', effect_description={'pirates.market_description_extra_time_at_sea'}},
-- },
}
function Public.get_cabin_surface_name()
@ -264,7 +267,7 @@ function Public.create_cabin_surface()
end
rendering.draw_text{
text = 'Captain\'s Cabin',
text = {'pirates.surface_label_cabin'},
surface = surface,
target = Public.Data.surfacename_rendering_pos,
color = CoreData.colors.renderingtext_yellow,

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
-- local Math = require 'maps.pirates.math'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
-- local Math = require 'maps.pirates.math'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Balance = require 'maps.pirates.balance'
@ -250,7 +252,7 @@ function Public.create_crowsnest_surface()
-- end
memory.crowsnest_surfacename_rendering = rendering.draw_text{
text = 'Crow\'s Nest',
text = {'pirates.surface_label_crowsnest'},
surface = surface,
target = Public.Data.surfacename_rendering_pos,
color = CoreData.colors.renderingtext_yellow,

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -16,7 +18,7 @@ local CustomEvents = require 'maps.pirates.custom_events'
local Public = {}
Public.Data = {}
Public.Data.display_names = {'Dock'}
Public.Data.display_names = {{'pirates.location_displayname_dock_1'}}
Public.Data.discord_emoji = CoreData.comfy_emojis.smolfish
Public.Data.width = 296
Public.Data.height = 98

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
-- local Math = require 'maps.pirates.math'
@ -32,6 +34,13 @@ Public.Data.downstairs_pole_positions = {
{x = -1, y = 5},
}
Public.Data.helper_text_rendering_positions = {
{x = -46.5, y = -3.5},
{x = 46.5, y = -3.5},
{x = -46.5, y = 2.5},
{x = 46.5, y = 2.5},
}
Public[enum.INITIAL] = {}
Public[enum.INITIAL].Data = {}
Public[enum.INITIAL].Data.hold_whitebelts_lrtp_order = {
@ -153,6 +162,21 @@ function Public.create_hold_surface(nth)
end
end
if (not boat.hold_helper_renderings) then boat.hold_helper_renderings = {} end
boat.hold_helper_renderings[nth] = {}
for i, p in ipairs(Public.Data.helper_text_rendering_positions) do
local alignment = i % 2 == 0 and 'left' or 'right'
boat.hold_helper_renderings[nth][i] = rendering.draw_text{
surface = surface,
target = p,
color = CoreData.colors.renderingtext_green,
scale = 1,
font = 'default-game',
alignment = alignment,
text = {'pirates.hold_connections_label_inactive'},
}
end
Common.build_small_loco(surface, Public.Data.loco_offset, memory.force, {255, 106, 52})
-- We place obstacle boxes before the other static boxes, so that they are potentially one tile closer to the edge than they would be otherwise:
@ -187,10 +211,10 @@ function Public.create_hold_surface(nth)
end
if subtype == enum.SECONDARY then
local difficulty_name = CoreData.get_difficulty_name_from_value(memory.difficulty)
if difficulty_name == CoreData.difficulty_options[#CoreData.difficulty_options].text then
local difficulty_name = CoreData.get_difficulty_option_informal_name_from_value(memory.difficulty)
if difficulty_name == 'nightmare' then
Public.upgrade_chests(nth, 'steel-chest')
elseif difficulty_name ~= CoreData.difficulty_options[1].text then
elseif difficulty_name ~= 'easy' then
Public.upgrade_chests(nth, 'iron-chest')
end
@ -199,7 +223,7 @@ function Public.create_hold_surface(nth)
if nth==1 then
memory.shiphold_rendering_1 = rendering.draw_text{
text = 'Ship\'s Hold',
text = {'pirates.surface_label_hold'},
surface = surface,
target = Public.Data.surfacename_rendering_pos,
color = CoreData.colors.renderingtext_yellow,
@ -210,11 +234,11 @@ function Public.create_hold_surface(nth)
else
if nth==2 then
if memory.shiphold_rendering_1 then
rendering.set_text(memory.shiphold_rendering_1, 'Ship\'s Hold: -1')
rendering.set_text(memory.shiphold_rendering_1, {'pirates.surface_label_hold_nth', 1})
end
end
rendering.draw_text{
text = 'Ship\'s Hold: -' .. nth,
text = {'pirates.surface_label_hold_nth', nth},
surface = surface,
target = Public.Data.surfacename_rendering_pos,
color = CoreData.colors.renderingtext_yellow,
@ -311,11 +335,16 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
{7,15},
{8,16},
}
for _, c in pairs(connections) do
for i, c in pairs(connections) do
local b1 = boat.hold_whitebelts[nth][c[1]]
local b2 = boat.hold_whitebelts[nth-1][c[2]]
b1.connect_linked_belts(b2)
end
rendering.set_text(boat.hold_helper_renderings[nth][3], {'pirates.hold_connections_label_from', nth-1})
rendering.set_text(boat.hold_helper_renderings[nth-1][3], {'pirates.hold_connections_label_to', nth})
rendering.set_text(boat.hold_helper_renderings[nth][4], {'pirates.hold_connections_label_from', nth-1})
rendering.set_text(boat.hold_helper_renderings[nth-1][4], {'pirates.hold_connections_label_to', nth})
else
connections = {
{5,5},
@ -328,6 +357,11 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
local b2 = boat.hold_whitebelts[nth-1][c[2]]
b1.connect_linked_belts(b2)
end
rendering.set_text(boat.hold_helper_renderings[nth][3], {'pirates.hold_connections_label_from', nth-1})
rendering.set_text(boat.hold_helper_renderings[nth-1][3], {'pirates.hold_connections_label_to', nth})
rendering.set_text(boat.hold_helper_renderings[nth][4], {'pirates.hold_connections_label_from', nth-1})
rendering.set_text(boat.hold_helper_renderings[nth-1][4], {'pirates.hold_connections_label_to', nth})
end
connections = {
{1,9},
@ -340,6 +374,11 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
local b2 = boat.hold_whitebelts[1][c[2]]
b1.connect_linked_belts(b2)
end
rendering.set_text(boat.hold_helper_renderings[nth][1], {'pirates.hold_connections_label_to', 1})
rendering.set_text(boat.hold_helper_renderings[1][1], {'pirates.hold_connections_label_from', nth})
rendering.set_text(boat.hold_helper_renderings[nth][2], {'pirates.hold_connections_label_to', 1})
rendering.set_text(boat.hold_helper_renderings[1][2], {'pirates.hold_connections_label_from', nth})
else
connections = {
{1,1},
@ -352,6 +391,12 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
local b2 = boat.hold_whitebelts[nth-1][c[2]]
b1.connect_linked_belts(b2)
end
rendering.set_text(boat.hold_helper_renderings[nth][1], {'pirates.hold_connections_label_from', nth-1})
rendering.set_text(boat.hold_helper_renderings[nth-1][1], {'pirates.hold_connections_label_to', nth})
rendering.set_text(boat.hold_helper_renderings[nth][2], {'pirates.hold_connections_label_from', nth-1})
rendering.set_text(boat.hold_helper_renderings[nth-1][2], {'pirates.hold_connections_label_to', nth})
connections = {
{5,9},
{6,10},
@ -363,6 +408,11 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
local b2 = boat.hold_whitebelts[1][c[2]]
b1.connect_linked_belts(b2)
end
rendering.set_text(boat.hold_helper_renderings[nth][3], {'pirates.hold_connections_label_to', 1})
rendering.set_text(boat.hold_helper_renderings[1][1], {'pirates.hold_connections_label_from', nth})
rendering.set_text(boat.hold_helper_renderings[nth][4], {'pirates.hold_connections_label_to', 1})
rendering.set_text(boat.hold_helper_renderings[1][2], {'pirates.hold_connections_label_from', nth})
end
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Fledgling Vale'}
Public.display_names = {{'pirates.location_displayname_first_1'}}
Public.terraingen_frame_width = 325
Public.terraingen_frame_height = 325

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -59,13 +61,17 @@ function Public.terrain(args)
if noises.height(p) > 0.2 then
if noises.forest_abs(p) > 0.65 then
local treedensity = 0.4 * Math.slopefromto(noises.forest_abs_suppressed(p), 0.6, 0.85)
if noises.forest(p) > 0.87 then
if Math.random(1,100) < treedensity*100 then args.entities[#args.entities + 1] = {name = 'tree-01', position = args.p, visible_on_overworld = true} end
elseif noises.forest(p) < -1.4 then
if Math.random(1,100) < treedensity*100 then args.entities[#args.entities + 1] = {name = 'tree-03', position = args.p, visible_on_overworld = true} end
if (not args.iconized_generation) and Math.random(1600) == 1 then
args.specials[#args.specials + 1] = {name = 'chest', position = args.p}
else
if Math.random(1,100) < treedensity*100 then args.entities[#args.entities + 1] = {name = 'tree-02', position = args.p, visible_on_overworld = true} end
local treedensity = 0.4 * Math.slopefromto(noises.forest_abs_suppressed(p), 0.6, 0.85)
if noises.forest(p) > 0.87 then
if Math.random(1,100) < treedensity*100 then args.entities[#args.entities + 1] = {name = 'tree-01', position = args.p, visible_on_overworld = true} end
elseif noises.forest(p) < -1.4 then
if Math.random(1,100) < treedensity*100 then args.entities[#args.entities + 1] = {name = 'tree-03', position = args.p, visible_on_overworld = true} end
else
if Math.random(1,100) < treedensity*100 then args.entities[#args.entities + 1] = {name = 'tree-02', position = args.p, visible_on_overworld = true} end
end
end
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Shark Keys', 'Little Keys', 'Little Keys'}
Public.display_names = {{'pirates.location_displayname_horseshoe_1'}, {'pirates.location_displayname_horseshoe_2'}, {'pirates.location_displayname_horseshoe_3'}}
Public.terraingen_frame_width = 896
Public.terraingen_frame_height = 896

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -15,6 +17,9 @@ local Public = {}
-- quest treasure
-- Something to be careful of whilst writing functions for this file:
-- Try to ensure that they only return integer co-ordinates, not half-integer. This will make structures easier to place.
@ -26,7 +31,7 @@ function Public.silo_setup_position(x_fractional_offset, x_absolute_offset)
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local boatposition = memory.boat.position
local island_center = destination.static_params.islandcenter_position
local island_center = Math.snap_to_grid(destination.static_params.islandcenter_position)
local difficulty_offset = (1 - Common.difficulty_scale()) * 20 or 0
local silo_count = Balance.silo_count()
@ -82,7 +87,7 @@ function Public.mid_farness_position_1(args, points_to_avoid)
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local island_center = destination.static_params.islandcenter_position
local island_center = Math.snap_to_grid(destination.static_params.islandcenter_position)
local width = destination.static_params.width
local height = destination.static_params.height
@ -144,7 +149,7 @@ function Public.close_position_try_avoiding_entities(args, points_to_avoid, farn
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local island_center = destination.static_params.islandcenter_position
local island_center = Math.snap_to_grid(destination.static_params.islandcenter_position)
local width = destination.static_params.width
local height = destination.static_params.height
@ -215,7 +220,7 @@ function Public.position_away_from_players_1(_, radius)
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local island_center = destination.static_params.islandcenter_position
local island_center = Math.snap_to_grid(destination.static_params.islandcenter_position)
local width = destination.static_params.width
local height = destination.static_params.height
@ -271,7 +276,7 @@ function Public.merchant_ship_position()
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local island_center = destination.static_params.islandcenter_position
local island_center = Math.snap_to_grid(destination.static_params.islandcenter_position)
local width = destination.static_params.width
local height = destination.static_params.height

View File

@ -1,8 +1,10 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
local Balance = require 'maps.pirates.balance'
local Structures = require 'maps.pirates.structures.structures'
-- local Structures = require 'maps.pirates.structures.structures'
local Boats = require 'maps.pirates.structures.boats.boats'
local Common = require 'maps.pirates.common'
local CoreData = require 'maps.pirates.coredata'
@ -14,6 +16,7 @@ local Quest = require 'maps.pirates.quest'
local _inspect = require 'utils.inspect'.inspect
local Token = require 'utils.token'
local Task = require 'utils.task'
local QuestStructures = require 'maps.pirates.structures.quest_structures.quest_structures'
local Public = {}
local enum = IslandsCommon.enum
@ -127,7 +130,7 @@ end
function Public.spawn_covered(destination, points_to_avoid)
function Public.spawn_quest_structure(destination, points_to_avoid)
points_to_avoid = points_to_avoid or {}
-- local memory = Memory.get_crew_memory()
local surface = game.surfaces[destination.surface_name]
@ -142,46 +145,9 @@ function Public.spawn_covered(destination, points_to_avoid)
for i = 1, 1 do
p = Hunt.mid_farness_position_1(args, points_to_avoid)
local structureData = Structures.IslandStructures.ROC.covered1.Data
local special = {
position = p,
components = structureData.components,
width = structureData.width,
height = structureData.height,
name = structureData.name,
}
if not destination.dynamic_data.structures_waiting_to_be_placed then
destination.dynamic_data.structures_waiting_to_be_placed = {}
if p then
QuestStructures.initialise_cached_quest_structure(p, QuestStructures.choose_quest_structure_type())
end
destination.dynamic_data.structures_waiting_to_be_placed[#destination.dynamic_data.structures_waiting_to_be_placed + 1] = {data = special, tick = game.tick}
local requirement = destination.dynamic_data.covered1_requirement.price
local rendering1 = rendering.draw_text{
surface = surface,
target = {x = p.x + 4, y = p.y + 6.85},
color = CoreData.colors.renderingtext_green,
scale = 1.5,
font = 'default-game',
alignment = 'right',
}
local rendering2 = rendering.draw_sprite{
sprite = 'item/' .. requirement.name,
surface = surface,
target = {x = p.x + 4.85, y = p.y + 7.5},
x_scale = 1.5,
y_scale = 1.5
}
destination.dynamic_data.covered_data = {
position = p,
state = 'covered',
requirement = requirement,
rendering1 = rendering1,
rendering2 = rendering2,
}
log('covered market position: ' .. p.x .. ', ' .. p.y)
end
return p
@ -212,32 +178,34 @@ function Public.spawn_ores_on_arrival(destination, points_to_avoid)
for _, ore in pairs(ores) do
if destination.static_params.abstract_ore_amounts[ore] then
local p = Hunt.close_position_try_avoiding_entities(args, points_to_avoid, farness_boost_low, farness_boost_high)
if p then points_to_avoid[#points_to_avoid + 1] = {x=p.x, y=p.y, r=11} end
if p then
points_to_avoid[#points_to_avoid + 1] = {x=p.x, y=p.y, r=11}
if ore == 'crude-oil' then
if ore == 'crude-oil' then
local count = Math.max(1, Math.ceil((destination.static_params.abstract_ore_amounts[ore]/3)^(1/2)))
local amount = Common.oil_abstract_to_real(destination.static_params.abstract_ore_amounts[ore]) / count
local count = Math.max(1, Math.ceil((destination.static_params.abstract_ore_amounts[ore]/3)^(1/2)))
local amount = Common.oil_abstract_to_real(destination.static_params.abstract_ore_amounts[ore]) / count
for i = 1, count do
local p2 = {p.x + Math.random(-7, 7), p.y + Math.random(-7, 7)}
local whilesafety = 0
while (not surface.can_place_entity{name = 'crude-oil', position = p2}) and whilesafety < 30 do
p2 = {p.x + Math.random(-7, 7), p.y + Math.random(-7, 7)}
whilesafety = whilesafety + 1
for i = 1, count do
local p2 = {p.x + Math.random(-7, 7), p.y + Math.random(-7, 7)}
local whilesafety = 0
while (not surface.can_place_entity{name = 'crude-oil', position = p2}) and whilesafety < 30 do
p2 = {p.x + Math.random(-7, 7), p.y + Math.random(-7, 7)}
whilesafety = whilesafety + 1
end
surface.create_entity{name = 'crude-oil', position = p2, amount = amount}
end
surface.create_entity{name = 'crude-oil', position = p2, amount = amount}
end
destination.dynamic_data.ore_types_spawned[ore] = true
else
local amount = Common.ore_abstract_to_real(destination.static_params.abstract_ore_amounts[ore])
local placed = Ores.draw_noisy_ore_patch(surface, p, ore, amount, 10000, 30, true, true)
if placed > 0 then
destination.dynamic_data.ore_types_spawned[ore] = true
else
local amount = Common.ore_abstract_to_real(destination.static_params.abstract_ore_amounts[ore])
local placed = Ores.draw_noisy_ore_patch(surface, p, ore, amount, 10000, 30, true, true)
if placed > 0 then
destination.dynamic_data.ore_types_spawned[ore] = true
end
end
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Bewildering Maze'}
Public.display_names = {{'pirates.location_displayname_maze_1'}}
Public.terraingen_frame_width = 896
Public.terraingen_frame_height = 896

View File

@ -1,6 +1,9 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
local Raffle = require 'maps.pirates.raffle'
-- local Balance = require 'maps.pirates.balance'
local Structures = require 'maps.pirates.structures.structures'
-- local Common = require 'maps.pirates.common'
@ -144,7 +147,8 @@ local free_labyrinth_cell_raffle = {
maze_belts_3 = 0.28,
maze_belts_4 = 0.28,
maze_mines = 0.1,
maze_treasure = 0.74,
maze_treasure = 0.92,
-- maze_treasure = 0.74,
}
local function free_labyrinth_cell_type(args)
@ -161,7 +165,7 @@ local function free_labyrinth_cell_type(args)
end
if not type then
type = Math.raffle2(free_labyrinth_cell_raffle)
type = Raffle.raffle2(free_labyrinth_cell_raffle)
cell_types[tostring(reduced_p.x) .. '_' .. tostring(reduced_p.y)] = type
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Abandoned Labs'}
Public.display_names = {{'pirates.location_displayname_radioactive_1'}}
Public.terraingen_frame_width = 700
Public.terraingen_frame_height = 700

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -58,12 +60,12 @@ function Public.terrain(args)
if noises.height(p) < 0.33 then
args.tiles[#args.tiles + 1] = {name = 'sand-2', position = args.p}
elseif noises.height(p) < 0.35 then
args.tiles[#args.tiles + 1] = {name = 'dirt-5', position = args.p}
args.tiles[#args.tiles + 1] = {name = 'dirt-1', position = args.p}
else
if noises.height_background(p) > 0.4 then
args.tiles[#args.tiles + 1] = {name = 'nuclear-ground', position = args.p}
else
args.tiles[#args.tiles + 1] = {name = 'dirt-4', position = args.p}
args.tiles[#args.tiles + 1] = {name = 'dirt-3', position = args.p}
end
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
local CoreData = require 'maps.pirates.coredata'
@ -6,7 +8,7 @@ local CoreData = require 'maps.pirates.coredata'
local Public = {}
Public.display_names = {'Sandworm Caldera'}
Public.display_names = {{'pirates.location_displayname_red_desert_1'}}
Public.discord_emoji = CoreData.comfy_emojis.mjau
@ -25,7 +27,7 @@ function Public.base_ores() --here, just for the visualisation:
return {
['copper-ore'] = 5,
['iron-ore'] = 5,
['coal'] = 5,
['coal'] = 3,
}
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -116,14 +118,14 @@ function Public.terrain(args)
if noises.forest_abs_suppressed(p) < 0.8 and noises.mood(p) > -0.3 then
if noises.height(p) > 0.27 then
if noises.ore(p) > 1.55 then
if noises.ore(p) > 1.5 then
local name = 'iron-ore'
if (args.p.x + args.p.y) % 2 < 1 then
name = 'copper-ore'
end
args.entities[#args.entities + 1] = {name = name, position = args.p, amount = 24}
args.entities[#args.entities + 1] = {name = name, position = args.p, amount = 20}
elseif noises.ore(p) < -1.6 then
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 24}
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 20}
elseif noises.ore(p) < 0.041 and noises.ore(p) > -0.041 then
args.entities[#args.entities + 1] = {name = 'stone', position = args.p, amount = 10}
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Isle of Buried Treasure'}
Public.display_names = {{'pirates.location_displayname_standard_1'}}
Public.terraingen_frame_width = 896
Public.terraingen_frame_height = 896

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -60,7 +62,7 @@ function Public.terrain(args)
if noises.height(p) > 0.06 then
if noises.forest_abs_suppressed(p) > 0.5 then
if (not args.iconized_generation) and noises.forest_abs_suppressed(p) < 0.75 and Math.random(2000) == 1 then
if (not args.iconized_generation) and noises.forest_abs_suppressed(p) < 0.75 and Math.random(1300) == 1 then
args.specials[#args.specials + 1] = {name = 'chest', position = args.p}
else
local forest_noise = noises.forest(p)

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Secluded Dells'}
Public.display_names = {{'pirates.location_displayname_standard_variant_1'}}
Public.terraingen_frame_width = 896
Public.terraingen_frame_height = 896

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -64,7 +66,7 @@ function Public.terrain(args)
if noises.height(p) > 0.11 then
if noises.forest_abs_suppressed(p) > 0.7 then
if (not args.iconized_generation) and noises.forest_abs_suppressed(p) < 1 and Math.random(750) == 1 then -- high amounts of this
if (not args.iconized_generation) and noises.forest_abs_suppressed(p) < 1 and Math.random(700) == 1 then -- high amounts of this
args.specials[#args.specials + 1] = {name = 'chest', position = args.p}
else
local forest_noise = noises.forest(p)

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Poisonous Fen'}
Public.display_names = {{'pirates.location_displayname_swamp_1'}}
Public.terraingen_frame_width = 325
Public.terraingen_frame_height = 325

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -66,7 +68,7 @@ function Public.terrain(args)
args.specials[#args.specials + 1] = {name = 'chest', position = args.p}
else
if noises.forest_abs(p) > 0.15 then
local treedensity = 0.08 * Math.slopefromto(noises.forest_abs_suppressed(p), 0.3, 0.6) + 0.3 * Math.slopefromto(noises.forest_abs_suppressed(p), 0.65, 1.0)
local treedensity = 0.08 * Math.slopefromto(noises.forest_abs_suppressed(p), 0.45, 0.6) + 0.3 * Math.slopefromto(noises.forest_abs_suppressed(p), 0.65, 1.0)
if noises.forest(p) > 1.3 then
if Math.random(1,100) < treedensity*100 then args.entities[#args.entities + 1] = {name = 'tree-09-brown', position = args.p} end
else
@ -127,8 +129,8 @@ function Public.chunk_structures(args)
placeable = noises.farness(p) > 0.3,
-- spawners_indestructible = noises.farness(p) > 0.75,
spawners_indestructible = false,
spawners_density_perchunk = 100 * Math.slopefromto(noises.mood(p), 0.7, 0.5) * Math.slopefromto(noises.farness(p), 0.35, 1)^2 * args.biter_base_density_scale,
worms_density_perchunk = 60 * Math.slopefromto(noises.mood(p), 0.7, 0.5) * Math.slopefromto(noises.farness(p), 0.25, 1)^2 * args.biter_base_density_scale,
spawners_density_perchunk = 90 * Math.slopefromto(noises.mood(p), 0.7, 0.5) * Math.slopefromto(noises.farness(p), 0.35, 1)^2 * args.biter_base_density_scale,
worms_density_perchunk = 30 * Math.slopefromto(noises.mood(p), 0.7, 0.5) * Math.slopefromto(noises.farness(p), 0.25, 1)^2 * args.biter_base_density_scale,
}
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
@ -5,7 +7,7 @@
local Public = {}
Public.display_names = {'Frozen Pools'}
Public.display_names = {{'pirates.location_displayname_walkways_1'}}
Public.terraingen_frame_width = 896
Public.terraingen_frame_height = 896

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -114,16 +116,18 @@ function Public.generate_silo_setup_position()
local p_silo = Hunt.silo_setup_position(0.2)
local tiles = {}
for x = -6.5, 6.5, 1 do
for y = -6.5, 6.5, 1 do
tiles[#tiles + 1] = {name = CoreData.world_concrete_tile, position = {x = p_silo.x + x, y = p_silo.y + y}}
if p_silo then
local tiles = {}
for x = -6.5, 6.5, 1 do
for y = -6.5, 6.5, 1 do
tiles[#tiles + 1] = {name = CoreData.world_concrete_tile, position = {x = p_silo.x + x, y = p_silo.y + y}}
end
end
end
Common.ensure_chunks_at(surface, p_silo, 1)
surface.set_tiles(tiles, true)
Common.ensure_chunks_at(surface, p_silo, 1)
surface.set_tiles(tiles, true)
return p_silo
return p_silo
end
end
@ -143,7 +147,7 @@ local function walkways_tick()
if player.force.name == memory.force_name and player.surface == game.surfaces[destination.surface_name] and player.character and player.character.valid and game.surfaces[destination.surface_name].get_tile(player.position).name == 'water-shallow' then
player.character.damage(12, game.forces['environment'], 'fire')
if not (player.character and player.character.valid) then
Common.notify_force(player.force, player.name .. ' froze to death.')
Common.notify_force(player.force, {'pirates.death_froze',player.name})
end
end
end

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -43,7 +45,7 @@ Public.StartingBoats = {
Public.Data = {}
Public.Data.display_name = 'Starting Dock'
Public.Data.display_name = {'pirates.location_displayname_lobby_1'}
Public.Data.width = 224
Public.Data.height = 128
-- Public.Data.noiseparams = {
@ -118,7 +120,7 @@ function Public.place_lobby_jetty_and_boats()
Public.place_starting_dock_showboat(id)
end
local offset = {x = -85, y = -23}
local offset = {x = -47, y = -1}
local tiles = {}
for _, p in pairs(Common.tile_positions_from_blueprint(Public.Data.jetty_bp, offset)) do

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -301,7 +303,8 @@ function Public.kraken_die(kraken_id)
local reward_fuel = Balance.kraken_kill_reward_fuel()
memory.stored_fuel = memory.stored_fuel + reward_fuel
Common.notify_force_light(memory.force,'Granted: ' .. Math.floor(reward_items[2].count/100)/10 .. 'k [item=coin], ' .. reward_fuel .. ' [item=coal], ' .. reward_items[1].count .. ' [item=sulfuric-acid-barrel].')
local message = {'pirates.granted_3', {'pirates.granted_kraken_kill'}, reward_items[2].count .. ' [item=coin]', reward_fuel .. ' [item=coal]', reward_items[1].count .. ' [item=sulfuric-acid-barrel]'}
Common.notify_force_light(memory.force,message)
memory.playtesting_stats.coins_gained_by_krakens = memory.playtesting_stats.coins_gained_by_krakens + reward_items[2].count
end

View File

@ -1,3 +1,4 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'

View File

@ -1,3 +1,5 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Math = require 'maps.pirates.math'
@ -15,7 +17,7 @@ local Cabin = require 'maps.pirates.surfaces.cabin'
local Islands = require 'maps.pirates.surfaces.islands.islands'
local Crowsnest = require 'maps.pirates.surfaces.crowsnest'
local Quest = require 'maps.pirates.quest'
local Parrot = require 'maps.pirates.parrot'
-- local Parrot = require 'maps.pirates.parrot'
local ShopMerchants = require 'maps.pirates.shop.merchants'
local SurfacesCommon = require 'maps.pirates.surfaces.common'
-- local Roles = require 'maps.pirates.roles.roles'
@ -134,7 +136,7 @@ function Public.destination_on_collide(destination)
local memory = Memory.get_crew_memory()
local name = destination.static_params.name and destination.static_params.name or 'NameNotFound'
local message = '[' .. memory.name .. '] Loading destination ' .. (memory.destinationsvisited_indices and (#memory.destinationsvisited_indices + 1) or 0) .. ', ' .. name .. '.'
local message = {'', '[' .. memory.name .. '] ', {'pirates.approaching_destination', memory.destinationsvisited_indices and (#memory.destinationsvisited_indices + 1) or 0, name}} --notify the whole server
Common.notify_game(message)
if destination.type ~= Public.enum.DOCK then
@ -161,7 +163,7 @@ function Public.destination_on_collide(destination)
if destination.subtype == Islands.enum.RADIOACTIVE then
Parrot.parrot_radioactive_tip_1()
Common.parrot_speak(memory.force, {'pirates.parrot_radioactive_tip_1'})
else
local scheduled_raft_raids
@ -169,14 +171,14 @@ function Public.destination_on_collide(destination)
local playercount = Common.activecrewcount()
local max_evo
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty_scale())
if difficulty_name == CoreData.difficulty_options[1].text then
local difficulty_name = CoreData.get_difficulty_option_informal_name_from_value(Common.difficulty_scale())
if difficulty_name == 'easy' then
if memory.overworldx/40 < 20 then
max_evo = 0.9 - (20 - memory.overworldx/40) * 1/100
else
max_evo = 0.91 + (memory.overworldx/40 - 20) * 0.25/100
end
elseif difficulty_name == CoreData.difficulty_options[2].text then
elseif difficulty_name == 'normal' then
if memory.overworldx/40 < 15 then
max_evo = 0.9 - (15 - memory.overworldx/40) * 0.5/100
else
@ -226,7 +228,7 @@ function Public.destination_on_collide(destination)
end
if memory.overworldx == 40*5 then
Parrot.parrot_boats_warning()
Common.parrot_speak(memory.force, {'pirates.parrot_boats_warning'})
-- elseif memory.overworldx == 800 then
-- Parrot.parrot_800_tip()
end
@ -262,7 +264,8 @@ function Public.destination_on_arrival(destination)
destination.dynamic_data.time_remaining = Math.ceil(Balance.max_time_on_island())
end
if destination.subtype ~= Islands.enum.FIRST and destination.subtype ~= Islands.enum.RADIOACTIVE then
if destination.subtype ~= Islands.enum.FIRST and destination.subtype ~= Islands.enum.RADIOACTIVE and destination.destination_index ~= 2 then
-- if not destination.overworld_position.x ~= Common.first_cost_to_leave_macrox * 40 then
Quest.initialise_random_quest()
-- else
-- if _DEBUG then
@ -318,9 +321,9 @@ function Public.destination_on_arrival(destination)
end
local name = destination.static_params.name and destination.static_params.name or 'NameNotFound'
local message = 'Approaching destination ' .. (memory.destinationsvisited_indices and #memory.destinationsvisited_indices or 0) .. ', ' .. name .. '.'
local message = {'pirates.approaching_destination', memory.destinationsvisited_indices and #memory.destinationsvisited_indices or 0, name}
if not (#memory.destinationsvisited_indices and #memory.destinationsvisited_indices == 1) then --don't need to notify for the first island
Server.to_discord_embed_raw((destination.static_params.discord_emoji or CoreData.comfy_emojis.wut) .. '[' .. memory.name .. '] Approaching ' .. name .. ', ' .. memory.overworldx .. ' leagues.')
Server.to_discord_embed_raw({'',(destination.static_params.discord_emoji or CoreData.comfy_emojis.wut) .. '[' .. memory.name .. '] Approaching ', name, ', ' .. memory.overworldx .. ' leagues.'}, true)
end
-- if destination.static_params.name == 'Dock' then
-- message = message .. ' ' .. 'New trades are available in the Captain\'s Store.'
@ -340,12 +343,14 @@ function Public.destination_on_arrival(destination)
Islands.spawn_ores_on_arrival(destination, points_to_avoid)
if memory.overworldx >= Balance.covered_first_appears_at and destination.subtype ~= Islands.enum.RADIOACTIVE then
if (memory.overworldx >= Balance.quest_structures_first_appear_at and destination.subtype ~= Islands.enum.RADIOACTIVE) or _DEBUG then
local class_for_sale = Classes.generate_class_for_sale()
destination.static_params.class_for_sale = class_for_sale
local covered = Islands.spawn_covered(destination, points_to_avoid)
points_to_avoid[#points_to_avoid + 1] = {x = covered.x, y = covered.y, r = 25}
local covered = Islands.spawn_quest_structure(destination, points_to_avoid)
if covered then
points_to_avoid[#points_to_avoid + 1] = {x = covered.x, y = covered.y, r = 25}
end
end
Islands.spawn_treasure_maps(destination, points_to_avoid)
@ -353,7 +358,7 @@ function Public.destination_on_arrival(destination)
if destination.subtype and destination.subtype == Islands.enum.MAZE then
local force = memory.force
force.manual_mining_speed_modifier = 0.8
force.manual_mining_speed_modifier = 1
end
end
end
@ -365,7 +370,7 @@ function Public.destination_on_departure(destination)
-- need to put tips only where we know there are islands:
if memory.overworldx == 40*9 then
Parrot.parrot_kraken_warning()
Common.parrot_speak(memory.force, {'pirates.parrot_kraken_warning'})
end
if destination.subtype and destination.subtype == Islands.enum.MAZE then
@ -392,9 +397,9 @@ function Public.destination_on_crewboat_hits_shore(destination)
destination.dynamic_data.initial_spawner_count = Common.spawner_count(game.surfaces[destination.surface_name])
if memory.overworldx == 0 then
Parrot.parrot_0()
Common.parrot_speak(memory.force, {'pirates.parrot_0'})
elseif memory.overworldx == 80 then
Parrot.parrot_80()
Common.parrot_speak(memory.force, {'pirates.parrot_night_warning'})
end
if destination.subtype == Islands.enum.RADIOACTIVE then
@ -408,9 +413,9 @@ function Public.destination_on_crewboat_hits_shore(destination)
surface.create_entity{name = 'electric-mining-drill', direction = direction, position = position}
end
Parrot.parrot_radioactive_tip_2()
Common.parrot_speak(memory.force, {'pirates.parrot_radioactive_tip_2'})
elseif destination.subtype == Islands.enum.MAZE and memory.overworldx == Common.maze_minimap_jam_league then
Parrot.parrot_maze_tip_1()
Common.parrot_speak(memory.force, {'pirates.parrot_maze_tip_1'})
end
if memory.merchant_ships_unlocked or _DEBUG then
@ -778,7 +783,7 @@ function Public.player_exit_crows_nest(player, player_relative_pos)
local memory = Memory.get_crew_memory()
local surface
if memory.boat and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
if memory.boat and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
surface = game.surfaces[SurfacesCommon.encode_surface_name(memory.id, 0, Public.enum.SEA, Public.Sea.enum.DEFAULT)]
else
surface = game.surfaces[Common.current_destination().surface_name]
@ -817,7 +822,7 @@ function Public.player_exit_hold(player, relative_pos)
local memory = Memory.get_crew_memory()
local surface
if memory.boat and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
if memory.boat and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
surface = game.surfaces[SurfacesCommon.encode_surface_name(memory.id, 0, Public.enum.SEA, Public.Sea.enum.DEFAULT)]
else
surface = game.surfaces[Common.current_destination().surface_name]
@ -834,7 +839,7 @@ end
function Public.player_goto_cabin(player, relative_pos)
-- local memory = Memory.get_crew_memory()
local memory = Memory.get_crew_memory()
local surface = Cabin.get_cabin_surface()
@ -843,6 +848,11 @@ function Public.player_goto_cabin(player, relative_pos)
local newpos2 = surface.find_non_colliding_position('character', newpos, 5, 0.2) or newpos
if newpos2 then player.teleport(newpos2, surface) end
if (not memory.captain_cabin_hint_given) and Common.is_captain(player) then
memory.captain_cabin_hint_given = true
Common.parrot_speak(memory.force, {'pirates.parrot_captain_first_time_in_cabin_hint'})
end
end
@ -850,7 +860,7 @@ function Public.player_exit_cabin(player, relative_pos)
local memory = Memory.get_crew_memory()
local surface
if memory.boat and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
if memory.boat and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
surface = game.surfaces[SurfacesCommon.encode_surface_name(memory.id, 0, Public.enum.SEA, Public.Sea.enum.DEFAULT)]
else
surface = game.surfaces[Common.current_destination().surface_name]

Some files were not shown because too many files have changed in this diff Show More