Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions schemas/player.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
"workers": {
"type": "integer",
"minimum": 0
},
"boatTier": {
"type": "integer",
"minimum": 0
},
"businessName": {
"type": "string"
}
},
"required": [
Expand Down
16 changes: 16 additions & 0 deletions schemas/stats.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@
"type": "string"
},
"description": "Names of milestones the player has already been awarded."
},
"totalWorkersHired": {
"type": "integer",
"description": "The lifetime number of workers hired for the fishing business."
},
"totalFishCaughtByCrew": {
"type": "integer",
"description": "The lifetime number of fish caught by the fishing business' crew."
},
"totalWagesPaid": {
"type": "number",
"description": "The lifetime total of wages paid to the fishing business' crew."
},
"daysInBusiness": {
"type": "integer",
"description": "The number of days the fishing business has produced a catch."
}
}
}
18 changes: 18 additions & 0 deletions src/achievements/achievements.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@
"threshold": 50,
"description": "Spend 50 hours fishing",
},
{
"name": "First Mate",
"stat": "totalWorkersHired",
"threshold": 1,
"description": "Hire your first crew member",
},
{
"name": "Full Crew",
"stat": "totalWorkersHired",
"threshold": 5,
"description": "Hire 5 crew members over your career",
},
{
"name": "Fishing Fleet Tycoon",
"stat": "totalFishCaughtByCrew",
"threshold": 500,
"description": "Have your crew catch 500 fish total",
},
]


Expand Down
36 changes: 33 additions & 3 deletions src/business/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,31 @@
WORKER_DAILY_WAGE = 10
WORKER_FISH_PER_DAY = 5

# Boat upgrades: a bigger boat holds more crew and each worker lands more fish
# per day. Tier 1 is exactly the original flat boat/crew numbers above, so
# existing saves and behavior are unchanged until a player chooses to upgrade.
BOAT_TIERS = [
{
"name": "Rowboat",
"cost": BOAT_PRICE,
"maxWorkers": MAX_WORKERS,
"fishPerDay": WORKER_FISH_PER_DAY,
},
{"name": "Trawler", "cost": 2000, "maxWorkers": 8, "fishPerDay": 7},
{"name": "Fishing Fleet", "cost": 6000, "maxWorkers": 12, "fishPerDay": 10},
]


def currentTier(player):
"""Resolve the player's effective boat tier (always >= 1 once they own a
boat). Older saves/tests may set hasBoat without ever touching boatTier,
so an unset (0) tier is treated as tier 1 - the original boat."""
return player.boatTier if player.boatTier > 0 else 1


def tierInfo(tier):
return BOAT_TIERS[tier - 1]


def runDailyProduction(player, stats=None):
"""Apply one day of the fishing business and return a summary.
Expand Down Expand Up @@ -43,13 +68,18 @@ def runDailyProduction(player, stats=None):
player.spendMoney(wages)
# Each worker fishes the same waters as the player, landing a rarity-rolled
# species (not just the cheapest one), so the crew's income is competitive
# with simply upgrading your own gear.
# with simply upgrading your own gear. A bigger boat means a bigger catch
# per worker, not just more worker slots.
fishPerWorker = tierInfo(currentTier(player))["fishPerDay"]
caught = 0
for _ in range(affordable):
player.addFish(fish.rollFishType(), WORKER_FISH_PER_DAY)
caught += WORKER_FISH_PER_DAY
player.addFish(fish.rollFishType(), fishPerWorker)
caught += fishPerWorker
summary["wagesPaid"] = wages
summary["fishCaught"] = caught
if stats is not None:
stats.totalFishCaught += caught
stats.totalFishCaughtByCrew += caught
stats.totalWagesPaid += wages
stats.daysInBusiness += 1
return summary
34 changes: 33 additions & 1 deletion src/location/bank.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from stats.stats import Stats
from ui.userInterface import UserInterface
from npc.npc import NPC
from business import business


# @author Daniel McCoy Stephenson
Expand Down Expand Up @@ -66,10 +67,41 @@ def __init__(
"Invest in good bait to improve your catches, but save the profits. "
"And remember: it's not about how much you earn, it's about how much you keep. "
"That's the secret to real wealth!"
}
},
{
"question": "What do you think of my fishing business?",
"response": self._businessDialogue,
},
]
)

def _businessDialogue(self):
"""Margaret's savings-minded take on the player's fishing business,
staged by boat ownership/crew size."""
if not self.player.hasBoat:
return (
"A boat's a fine goal to save toward! Set some money aside "
"here and it'll be waiting for you when you're ready to buy one."
)
if self.player.workers == 0:
return (
"A boat with no crew is just a rowboat and a dream! Bank your "
"catch money for a while and you'll have their wages covered "
"in no time."
)
if business.currentTier(self.player) >= 3:
return (
"A whole Fishing Fleet, paying out $%d in wages so far? "
"You could retire a wealthy soul if you keep banking those "
"profits!" % self.stats.totalWagesPaid
)
return (
"Your crew's brought in $%d in wages paid out so far - quite the "
"little enterprise! Don't let it all burn a hole in your pocket, "
"park some of it here and let it earn interest."
% self.stats.totalWagesPaid
)

def run(self):
li = ["Make a Deposit", "Make a Withdrawal", "Talk to %s" % self.npc.name, "Go to docks"]
input = self.userInterface.showOptions(
Expand Down
117 changes: 103 additions & 14 deletions src/location/docks.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ def __init__(
"Fish when you have energy, sell regularly, and save your money. "
"The sea has its rhythms - you'll learn them in time. "
"And remember: it's not just about catching fish, it's about enjoying the life!"
}
},
{
"question": "How's my fishing business doing?",
"response": self._businessDialogue,
},
]
)

Expand All @@ -94,9 +98,11 @@ def run(self):
"Go to Bank",
"Manage Boat & Crew",
]
input = self.userInterface.showOptions(
"You breathe in the fresh air. Salty.", li
)
if self.player.hasBoat and self.player.businessName:
descriptor = "%s is docked and ready for the day." % self.player.businessName
else:
descriptor = "You breathe in the fresh air. Salty."
input = self.userInterface.showOptions(descriptor, li)

if input == "1":
if self.player.hasEnergy(10):
Expand Down Expand Up @@ -133,19 +139,60 @@ def run(self):
self.manageBusiness()
return LocationType.DOCKS

def _businessDialogue(self):
"""Sam's take on the player's fishing business, staged by boat tier and
crew size so it reflects real progress rather than being fixed text."""
if not self.player.hasBoat:
return (
"No boat yet, eh? Once you've got one, I can help you find "
"good hands to hire. A crew changes everything!"
)
if self.player.workers == 0:
starter = business.tierInfo(business.currentTier(self.player))
return (
"A %s of your own! Now you just need to hire a crew to get "
"it earning." % starter["name"]
)
tier = business.currentTier(self.player)
name = self.player.businessName or "your business"
if tier == 1:
return (
"%s is off to a solid start with that Rowboat crew. Save up "
"and you could afford a bigger boat before long." % name
)
if tier == 2:
return (
"A Trawler! %s is really coming along. I've seen a lot of "
"fishermen never make it past a rowboat." % name
)
return (
"A whole Fishing Fleet under %s? You're the talk of the docks! "
"Never thought I'd see an outfit like that around here." % name
)

def _businessStatus(self):
if not self.player.hasBoat:
starter = business.tierInfo(1)
return (
"You have no boat. A boat lets you hire a crew that brings in a "
"passive catch each day. A boat costs $%d." % business.BOAT_PRICE
"passive catch each day. A %s costs $%d."
% (starter["name"], starter["cost"])
)
tier = business.currentTier(self.player)
info = business.tierInfo(tier)
name = self.player.businessName or "Unnamed Fishing Co."
return (
"Your crew: %d/%d workers. Each catches %d fish per day for $%d in "
"%s - %s (tier %d/%d)\n"
"Crew: %d/%d workers. Each catches %d fish per day for $%d in "
"wages, paid automatically every new day."
% (
name,
info["name"],
tier,
len(business.BOAT_TIERS),
self.player.workers,
business.MAX_WORKERS,
business.WORKER_FISH_PER_DAY,
info["maxWorkers"],
info["fishPerDay"],
business.WORKER_DAILY_WAGE,
)
)
Expand All @@ -155,18 +202,29 @@ def manageBusiness(self):
options = []
actions = []
if not self.player.hasBoat:
options.append("Buy a Boat ($%d)" % business.BOAT_PRICE)
starter = business.tierInfo(1)
options.append("Buy a %s ($%d)" % (starter["name"], starter["cost"]))
actions.append("buy_boat")
else:
if self.player.workers < business.MAX_WORKERS:
tier = business.currentTier(self.player)
info = business.tierInfo(tier)
if self.player.workers < info["maxWorkers"]:
options.append(
"Hire a Worker (+%d fish/day for $%d/day)"
% (business.WORKER_FISH_PER_DAY, business.WORKER_DAILY_WAGE)
% (info["fishPerDay"], business.WORKER_DAILY_WAGE)
)
actions.append("hire")
if self.player.workers > 0:
options.append("Dismiss a Worker")
actions.append("dismiss")
if tier < len(business.BOAT_TIERS):
nextInfo = business.tierInfo(tier + 1)
options.append(
"Upgrade to a %s ($%d)" % (nextInfo["name"], nextInfo["cost"])
)
actions.append("upgrade_boat")
options.append("Rename Business")
actions.append("rename")
options.append("Back")
actions.append("back")

Expand All @@ -176,24 +234,55 @@ def manageBusiness(self):
action = actions[choice - 1]

if action == "buy_boat":
if self.player.canAfford(business.BOAT_PRICE):
self.player.spendMoney(business.BOAT_PRICE)
starter = business.tierInfo(1)
if self.player.canAfford(starter["cost"]):
self.player.spendMoney(starter["cost"])
self.player.hasBoat = True
self.currentPrompt.text = "You bought a boat! Now hire a crew."
self.player.boatTier = 1
self.currentPrompt.text = (
"You bought a %s! Now hire a crew." % starter["name"]
)
else:
self.currentPrompt.text = "You can't afford a boat yet."
elif action == "hire":
self.player.workers += 1
self.stats.totalWorkersHired += 1
self.currentPrompt.text = (
"You hired a worker. They'll fish each day for their wage."
)
elif action == "dismiss":
self.player.workers -= 1
self.currentPrompt.text = "You let a worker go."
elif action == "upgrade_boat":
tier = business.currentTier(self.player)
nextInfo = business.tierInfo(tier + 1)
if self.player.canAfford(nextInfo["cost"]):
self.player.spendMoney(nextInfo["cost"])
self.player.boatTier = tier + 1
self.currentPrompt.text = (
"You upgraded to a %s!" % nextInfo["name"]
)
else:
self.currentPrompt.text = "You can't afford that upgrade yet."
elif action == "rename":
self._renameBusiness()
elif action == "back":
self.currentPrompt.text = "What would you like to do?"
return

def _renameBusiness(self):
name = self.userInterface.promptForText(
"What would you like to name your fishing business?"
)
name = (name or "").strip()[:40]
if name:
self.player.businessName = name
self.currentPrompt.text = "Your business is now known as %s!" % name
else:
self.currentPrompt.text = "Never mind - the name stays %s." % (
self.player.businessName or "Unnamed Fishing Co."
)

def getTimeOfDayModifier(self, hour):
"""Return (yield factor, flavour label) for fishing at the given hour.

Expand Down
11 changes: 11 additions & 0 deletions src/location/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ def displayStats(self):
"Money Made From Interest: %d" % self.stats.moneyMadeFromInterest,
"Times Gotten Drunk: %d" % self.stats.timesGottenDrunk,
"Money Lost Gambling: %d" % self.stats.moneyLostFromGambling,
]
if self.player.hasBoat:
lines += [
"",
"Business: %s" % (self.player.businessName or "Unnamed Fishing Co."),
"Days in Business: %d" % self.stats.daysInBusiness,
"Crew Hired (lifetime): %d" % self.stats.totalWorkersHired,
"Fish Caught by Crew: %d" % self.stats.totalFishCaughtByCrew,
"Wages Paid: %d" % self.stats.totalWagesPaid,
]
lines += [
"",
"Milestones:",
]
Expand Down
Loading
Loading