Masonry joins Construction; smith hardware; homesteader plots
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f4b2bb1320
commit
e825518c5e
6 changed files with 258 additions and 72 deletions
219
game.py
219
game.py
|
|
@ -167,6 +167,20 @@ for _tier, (_key, _name, _ore, _coal, _bar_icon, _bar_value, _smithy, _wood) in
|
|||
"name": f"{_name} {_tool}", "icon": _icon, "value": round(2 * _bar_value * 1.4), "tier": _tier,
|
||||
"slot": f"tool_{_skill}", "tool": _skill, "speed": TOOL_SPEED[_tier], "req": [_skill, EQUIP_LEVELS[_tier]],
|
||||
}
|
||||
# Hardware: what the smith makes for builders, one kind per metal, used in
|
||||
# fittings and in building levels in place of plain bars.
|
||||
# id, singular, plural, bars used, pieces made
|
||||
HARDWARE = [
|
||||
("copper_rivets", "Copper rivet", "Copper rivets", 1, 5),
|
||||
("iron_nails", "Iron nail", "Iron nails", 1, 5),
|
||||
("steel_hinges", "Steel hinge", "Steel hinges", 1, 2),
|
||||
("mithril_brackets", "Mithril bracket", "Mithril brackets", 1, 2),
|
||||
("adamant_chain", "Adamant chain", "Adamant chains", 2, 1),
|
||||
("rune_lock", "Rune lock", "Rune locks", 2, 1),
|
||||
]
|
||||
for (_id, _name, _plural, _bars, _made), _metal in zip(HARDWARE, METALS):
|
||||
ITEMS[_id] = {"name": _name, "plural": _plural, "icon": "🔩", "value": max(1, round(_bars * _metal[5] * 1.2 / _made)),
|
||||
"tier": METALS.index(_metal)}
|
||||
PLANKS = [("plank", "Plank"), ("oak_plank", "Oak plank"), ("willow_plank", "Willow plank"),
|
||||
("maple_plank", "Maple plank"), ("yew_plank", "Yew plank"), ("magic_plank", "Enchanted plank")]
|
||||
for (_log, _name, _icon, _value, _action_id, _verb), (_plank, _plank_name) in zip(TREES, PLANKS):
|
||||
|
|
@ -221,7 +235,6 @@ POTION_LINES = [
|
|||
("cooking", "Cooking potion", "cooking", "keep", SPEEDS, [fish[1][0] for fish in FISH]),
|
||||
("leatherworking", "Leatherworking potion", "leatherworking", "keep", SPEEDS,
|
||||
[leather[1][0] for leather in LEATHERS]),
|
||||
("masonry", "Masonry potion", "masonry", "keep", SPEEDS[:3], ["stone", "bricks", "cut_stone"]),
|
||||
("prayer", "Prayer potion", "prayer", "bones", [0.25, 0.5, 0.75], ["bones", "big_bones", "dragon_bones"]),
|
||||
("strength", "Strength potion", "combat", "power", [4, 7, 11, 15, 20, 26], [leather[0][0] for leather in LEATHERS]),
|
||||
("defence", "Defence potion", "combat", "reduce", [0.10, 0.14, 0.18, 0.22, 0.26, 0.30],
|
||||
|
|
@ -242,7 +255,7 @@ OLD_POTIONS = {
|
|||
"strength_potion": "strength_potion_2", "anglers_brew": "fishing_potion_3",
|
||||
"prospectors_draught": "mining_potion_2", "growth_potion": "farming_potion_3",
|
||||
"defence_potion": "defence_potion_2", "chefs_spice": "cooking_potion_2", "bonedust_tonic": "prayer_potion_2",
|
||||
"smiths_focus": "smithing_potion_2", "masons_patience": "masonry_potion_2", "tanners_oil": "leatherworking_potion_2",
|
||||
"smiths_focus": "smithing_potion_2", "masons_patience": "construction_potion_2", "tanners_oil": "leatherworking_potion_2",
|
||||
"regeneration_potion": "defence_potion_3", "super_strength": "strength_potion_4", "super_defence": "defence_potion_5",
|
||||
}
|
||||
|
||||
|
|
@ -280,7 +293,6 @@ SKILLS = [
|
|||
{"id": "hunting", "name": "Hunting", "icon": "🦌", "group": "Gathering"},
|
||||
{"id": "fishing", "name": "Fishing", "icon": "🎣", "group": "Gathering"},
|
||||
{"id": "smithing", "name": "Smithing", "icon": "🔨", "group": "Crafting"},
|
||||
{"id": "masonry", "name": "Masonry", "icon": "🧱", "group": "Crafting"},
|
||||
{"id": "construction", "name": "Construction", "icon": "🏗️", "group": "Crafting"},
|
||||
{"id": "cooking", "name": "Cooking", "icon": "🍳", "group": "Crafting"},
|
||||
{"id": "leatherworking", "name": "Leatherworking", "icon": "🪡", "group": "Crafting"},
|
||||
|
|
@ -291,7 +303,7 @@ SKILLS = [
|
|||
]
|
||||
SKILL_IDS = [skill["id"] for skill in SKILLS]
|
||||
GATHERING = {"mining", "woodcutting", "farming", "hunting", "fishing"}
|
||||
CRAFTING = {"smithing", "masonry", "construction", "cooking", "leatherworking", "herblore"}
|
||||
CRAFTING = {"smithing", "construction", "cooking", "leatherworking", "herblore"}
|
||||
|
||||
# A class is a whole trade, from gathering to the finished goods: its skills are
|
||||
# 20% faster, 1 in 10 of its crafts make double, and it has one bonus of its own.
|
||||
|
|
@ -304,16 +316,14 @@ CLASSES = {
|
|||
"signature": "Prospector: 1 in 10 mining trips bring back double",
|
||||
},
|
||||
"builder": {
|
||||
"name": "Builder", "icon": "🏗️", "fast": ["woodcutting", "construction", "masonry"],
|
||||
"craft": ["construction", "masonry"],
|
||||
"bonus": "Woodcutting, construction and masonry 20% faster",
|
||||
"masterwork": "Masterwork: 1 in 10 construction and masonry crafts make double",
|
||||
"name": "Builder", "icon": "🏗️", "fast": ["woodcutting", "construction"], "craft": ["construction"],
|
||||
"bonus": "Woodcutting and construction (masonry included) 20% faster",
|
||||
"masterwork": "Masterwork: 1 in 10 construction crafts make double",
|
||||
"signature": "Foreman: +1 labour every time you work a building site",
|
||||
},
|
||||
"homesteader": {
|
||||
"name": "Homesteader", "icon": "🌾", "fast": ["farming", "cooking", "herblore"],
|
||||
"craft": ["cooking", "herblore"],
|
||||
"bonus": "Farming, cooking and herblore 20% faster",
|
||||
"name": "Homesteader", "icon": "🌾", "fast": ["cooking", "herblore"], "craft": ["cooking", "herblore"],
|
||||
"bonus": "Cooking and herblore 20% faster. Two plots: farm one crop 30% faster, or two crops at once",
|
||||
"masterwork": "Masterwork: 1 in 10 cooking and herblore crafts make double",
|
||||
"signature": "Steady hand: potions you drink last 25% longer",
|
||||
},
|
||||
|
|
@ -354,6 +364,10 @@ def _tiered_actions() -> list[dict]:
|
|||
actions.append(_action(f"smith_{key}_bar", "smithing", f"{name} bar", TIER_LEVELS[tier], 20 + 4 * tier,
|
||||
bar_xp[tier], inputs, {f"{key}_bar": 1}, group="Bars",
|
||||
city={"smithy": smithy} if tier >= 2 else {}))
|
||||
hardware, _name, _plural, bars, made = HARDWARE[tier]
|
||||
actions.append(_action(f"smith_{hardware}", "smithing", _plural, TIER_LEVELS[tier] + 2, 25 + 2 * tier,
|
||||
bars * piece_xp[tier], {f"{key}_bar": bars}, {hardware: made}, group="Hardware",
|
||||
city=city))
|
||||
for piece, _slot, noun, bars, offset, _power, _armour in PIECES:
|
||||
actions.append(_action(f"smith_{key}_{piece}", "smithing", f"{name} {noun}", TIER_LEVELS[tier] + offset,
|
||||
25 + 5 * bars + 2 * tier, bars * piece_xp[tier], {f"{key}_bar": bars},
|
||||
|
|
@ -413,10 +427,10 @@ ACTIONS = [
|
|||
*[_action(f"saw_{plank}", "construction", f"Saw {name.lower()}s", TIER_LEVELS[tier], 25 + 3 * tier,
|
||||
[6, 14, 22, 32, 44, 58][tier], {TREES[tier][0]: 2}, {plank: 1}, group="Planks")
|
||||
for tier, (plank, name) in enumerate(PLANKS)],
|
||||
_action("mason_bricks", "masonry", "Bricks", 1, 25, 6, {"stone": 2, "logs": 1}, {"bricks": 2}),
|
||||
_action("mason_cut_stone", "masonry", "Cut stone", 10, 30, 12, {"stone": 3}, {"cut_stone": 1}),
|
||||
_action("mason_beam", "masonry", "Reinforced beam", 20, 45, 30,
|
||||
{"oak_logs": 2, "iron_bar": 1}, {"beam": 1}),
|
||||
_action("mason_bricks", "construction", "Bricks", 1, 25, 6, {"stone": 2, "logs": 1}, {"bricks": 2}, group="Masonry"),
|
||||
_action("mason_cut_stone", "construction", "Cut stone", 10, 30, 12, {"stone": 3}, {"cut_stone": 1}, group="Masonry"),
|
||||
_action("mason_beam", "construction", "Reinforced beam", 20, 45, 30,
|
||||
{"oak_logs": 2, "iron_nails": 5}, {"beam": 1}, group="Masonry"),
|
||||
_action("cook_bread", "cooking", "Bread", 1, 20, 5, {"wheat": 2, "logs": 1}, {"bread": 1}),
|
||||
_action("cook_meat", "cooking", "Cooked meat", 5, 20, 7, {"raw_meat": 1, "logs": 1}, {"cooked_meat": 1}),
|
||||
_action("cook_stew", "cooking", "Stew", 15, 35, 16,
|
||||
|
|
@ -457,23 +471,23 @@ ACTION_BY_ID = {action["id"]: action for action in ACTIONS}
|
|||
BUILDINGS = {
|
||||
"houses": {
|
||||
"name": "Houses", "icon": "🏠", "max": 8, "gold": 200,
|
||||
"base": {"logs": 300, "bricks": 150, "thatch": 300, "provisions": 80},
|
||||
"advanced": {"oak_logs": 100, "leather": 80, "rope": 40, "iron_bar": 30},
|
||||
"late": {"willow_logs": 80, "oak_plank": 35, "hide_glue": 50},
|
||||
"final": {"maple_logs": 50, "willow_plank": 30, "hard_leather": 60},
|
||||
"base": {"logs": 300, "bricks": 150, "thatch": 300, "provisions": 80, "copper_rivets": 60},
|
||||
"advanced": {"oak_logs": 100, "leather": 80, "rope": 40, "iron_nails": 150},
|
||||
"late": {"willow_logs": 80, "oak_plank": 35, "hide_glue": 50, "steel_hinges": 20},
|
||||
"final": {"maple_logs": 50, "willow_plank": 30, "hard_leather": 60, "mithril_brackets": 15},
|
||||
"effect": "Room for 20 more people per level",
|
||||
},
|
||||
"walls": {
|
||||
"name": "Walls", "icon": "🏰", "max": 5, "gold": 300,
|
||||
"base": {"stone": 1000, "bricks": 250, "provisions": 90},
|
||||
"advanced": {"cut_stone": 150, "beam": 20, "rope": 50, "iron_bar": 40},
|
||||
"late": {"steel_bar": 80, "oak_plank": 25, "hide_glue": 50},
|
||||
"final": {"mithril_bar": 50, "maple_plank": 20, "hide_glue": 60},
|
||||
"advanced": {"cut_stone": 150, "beam": 20, "rope": 50, "iron_nails": 200},
|
||||
"late": {"steel_bar": 60, "oak_plank": 25, "hide_glue": 50, "steel_hinges": 30},
|
||||
"final": {"mithril_brackets": 60, "maple_plank": 20, "hide_glue": 60, "adamant_chain": 10},
|
||||
"effect": "+20 defence per level, and raiders carry off less",
|
||||
},
|
||||
"barracks": {
|
||||
"name": "Barracks", "icon": "⛺", "max": 5, "gold": 300,
|
||||
"base": {"logs": 300, "bricks": 200, "thatch": 200, "leather": 80, "copper_sword": 25, "provisions": 80},
|
||||
"base": {"logs": 300, "bricks": 200, "thatch": 200, "leather": 80, "copper_sword": 25, "provisions": 80, "copper_rivets": 60},
|
||||
"advanced": {"iron_sword": 20, "hard_leather": 40},
|
||||
"late": {"steel_sword": 12, "oak_plank": 30, "hide_glue": 40},
|
||||
"final": {"mithril_sword": 8, "willow_plank": 25, "bear_leather": 40},
|
||||
|
|
@ -490,44 +504,44 @@ BUILDINGS = {
|
|||
"temple": {
|
||||
"name": "Temple", "icon": "⛪", "max": 3, "gold": 300,
|
||||
"base": {"stone": 700, "bricks": 200, "cut_stone": 60, "provisions": 60},
|
||||
"advanced": {"beam": 15, "rope": 40, "iron_bar": 30},
|
||||
"late": {"willow_logs": 80, "oak_plank": 35, "hide_glue": 40},
|
||||
"advanced": {"beam": 15, "rope": 40, "iron_nails": 150},
|
||||
"late": {"willow_logs": 80, "oak_plank": 35, "hide_glue": 40, "steel_hinges": 20},
|
||||
"effect": "Offerings ward the city in raids; +1 prayer point per bone buried and +25% devotion per level",
|
||||
},
|
||||
"granary": {
|
||||
"name": "Granary", "icon": "🌾", "max": 3, "gold": 150,
|
||||
"base": {"logs": 200, "bricks": 100, "plank": 40, "thatch": 300, "provisions": 50},
|
||||
"advanced": {"cut_stone": 40, "rope": 40, "iron_bar": 20},
|
||||
"late": {"oak_plank": 35, "hide_glue": 35},
|
||||
"base": {"logs": 200, "bricks": 100, "plank": 40, "thatch": 300, "provisions": 50, "copper_rivets": 40},
|
||||
"advanced": {"cut_stone": 40, "rope": 40, "iron_nails": 100},
|
||||
"late": {"oak_plank": 35, "hide_glue": 35, "steel_hinges": 15},
|
||||
"effect": "Protects a quarter of the food from locusts and rats per level",
|
||||
},
|
||||
"lumber_shed": {
|
||||
"name": "Lumber shed", "icon": "🪵", "max": 3, "gold": 120,
|
||||
"base": {"logs": 200, "stone": 250, "plank": 50, "thatch": 180, "provisions": 40},
|
||||
"advanced": {"oak_plank": 40, "rope": 40, "iron_bar": 20},
|
||||
"base": {"logs": 200, "stone": 250, "plank": 50, "thatch": 180, "provisions": 40, "copper_rivets": 40},
|
||||
"advanced": {"oak_plank": 40, "rope": 40, "iron_nails": 100},
|
||||
"late": {"willow_plank": 25, "hide_glue": 35},
|
||||
"effect": "Keeps a quarter of the stored wood safe from rot per level",
|
||||
},
|
||||
"well": {
|
||||
"name": "Well", "icon": "🪣", "max": 3, "gold": 120,
|
||||
"base": {"stone": 500, "bricks": 80, "rope": 50, "provisions": 40},
|
||||
"advanced": {"cut_stone": 40, "leather": 60, "iron_bar": 25},
|
||||
"late": {"oak_plank": 25, "hide_glue": 35},
|
||||
"advanced": {"cut_stone": 40, "leather": 60, "iron_nails": 125},
|
||||
"late": {"oak_plank": 25, "hide_glue": 35, "steel_hinges": 15},
|
||||
"effect": "Each level cuts fire losses by a quarter and may save the building",
|
||||
},
|
||||
"spymaster": {
|
||||
"name": "Spymaster's guild", "icon": "🕵️", "max": 3, "gold": 400,
|
||||
"base": {"logs": 200, "bricks": 150, "hide": 120, "feathers": 300, "provisions": 60},
|
||||
"advanced": {"cut_stone": 80, "hard_leather": 40, "iron_bar": 20},
|
||||
"late": {"bear_leather": 50, "oak_plank": 25},
|
||||
"advanced": {"cut_stone": 80, "hard_leather": 40, "iron_nails": 100},
|
||||
"late": {"bear_leather": 50, "oak_plank": 25, "steel_hinges": 15},
|
||||
"effect": "+25% reconnaissance per level, and its agents gather some every hour on their own",
|
||||
},
|
||||
"storehouse": {
|
||||
"name": "Storehouse", "icon": "📦", "max": 5, "gold": 200,
|
||||
"base": {"logs": 400, "stone": 800, "thatch": 200, "provisions": 60},
|
||||
"advanced": {"oak_logs": 150, "cut_stone": 100, "rope": 50, "iron_bar": 30},
|
||||
"late": {"willow_logs": 120, "oak_plank": 45, "hide_glue": 45},
|
||||
"final": {"yew_logs": 40, "yew_plank": 20, "bear_leather": 40},
|
||||
"base": {"logs": 400, "stone": 800, "thatch": 200, "provisions": 60, "copper_rivets": 60},
|
||||
"advanced": {"oak_logs": 150, "cut_stone": 100, "rope": 50, "iron_nails": 150},
|
||||
"late": {"willow_logs": 120, "oak_plank": 45, "hide_glue": 45, "steel_hinges": 25},
|
||||
"final": {"yew_logs": 40, "yew_plank": 20, "bear_leather": 40, "rune_lock": 6},
|
||||
"effect": "+3 bank slots and +250 per stack for everyone, per level",
|
||||
},
|
||||
}
|
||||
|
|
@ -564,7 +578,7 @@ RAID_TRAITS = ["lightly armoured, heavy on archers", "mounted and fast, few bows
|
|||
|
||||
# --- world ---------------------------------------------------------------
|
||||
|
||||
WORLD_VERSION = 12
|
||||
WORLD_VERSION = 13
|
||||
|
||||
|
||||
def new_world(now: float, speed: float = 1.0) -> dict:
|
||||
|
|
@ -681,6 +695,10 @@ def migrate(world: dict, now: float | None = None) -> dict:
|
|||
player["repick"] = True
|
||||
_return_overfunding(world)
|
||||
world["version"] = 12
|
||||
if world["version"] < 13:
|
||||
_fold_masonry(world)
|
||||
_return_overfunding(world)
|
||||
world["version"] = 13
|
||||
return world
|
||||
|
||||
|
||||
|
|
@ -704,6 +722,32 @@ def _migrate_potions(world: dict) -> None:
|
|||
action[key] = f"brew_{OLD_POTIONS[old]}"
|
||||
|
||||
|
||||
def _fold_masonry(world: dict) -> None:
|
||||
"""Masonry became part of Construction: its XP, potions and brews carry over."""
|
||||
moved = {f"masonry_potion_{tier}": f"construction_potion_{tier}" for tier in (1, 2, 3)}
|
||||
def renamed(stock: dict) -> None:
|
||||
for old, new in moved.items():
|
||||
if old in stock:
|
||||
stock[new] = stock.get(new, 0) + stock.pop(old)
|
||||
renamed(world["city"]["stockpile"])
|
||||
for player in world["players"].values():
|
||||
player["xp"]["construction"] = player["xp"].get("construction", 0) + player["xp"].pop("masonry", 0)
|
||||
renamed(player["bank"])
|
||||
active = player["potions"].pop("masonry", None)
|
||||
if active:
|
||||
item = moved.get(active["item"], active["item"])
|
||||
if "construction" in player["potions"]:
|
||||
player["bank"][item] = player["bank"].get(item, 0) + 1 # a fresh one back, rather than lose it
|
||||
else:
|
||||
player["potions"]["construction"] = {"item": item, "charges": active["charges"]}
|
||||
action = player["action"]
|
||||
if action:
|
||||
for key in ("id", "resume"):
|
||||
brew = (action.get(key) or "").removeprefix("brew_")
|
||||
if brew in moved:
|
||||
action[key] = f"brew_{moved[brew]}"
|
||||
|
||||
|
||||
def _return_overfunding(world: dict) -> None:
|
||||
"""After building costs change, anything a fund holds beyond its new target goes back to the stockpile."""
|
||||
city = world["city"]
|
||||
|
|
@ -1038,6 +1082,9 @@ def action_time(world: dict, player: dict, action: dict) -> float:
|
|||
seconds = action["time"]
|
||||
if action["skill"] in CLASSES[player["cls"]]["fast"]:
|
||||
seconds *= CLASS_SPEED
|
||||
if action["skill"] == "farming" and player["cls"] == "homesteader":
|
||||
# Focus on one plot for 30% faster, or split the same 20% pace between two crops.
|
||||
seconds *= PLOTS_SPEED if two_plots(player) else FOCUS_SPEED
|
||||
tool = player["equip"].get(f"tool_{action['skill']}")
|
||||
if tool:
|
||||
seconds *= 1 - ITEMS[tool]["speed"]
|
||||
|
|
@ -1051,6 +1098,48 @@ def action_time(world: dict, player: dict, action: dict) -> float:
|
|||
return seconds / speed(world)
|
||||
|
||||
|
||||
FOCUS_SPEED = 0.7 # a homesteader tending one plot
|
||||
PLOTS_SPEED = 0.8 # each harvest when tending two: together, one crop's worth at 20% faster
|
||||
|
||||
|
||||
def two_plots(player: dict) -> bool:
|
||||
current = player["action"]
|
||||
return bool(current and current.get("plot2"))
|
||||
|
||||
|
||||
def growing(player: dict) -> dict:
|
||||
"""The action the player is on right now: with two plots, harvests alternate between them."""
|
||||
current = player["action"]
|
||||
if current.get("plot2") and current.get("turn"):
|
||||
return ACTION_BY_ID[current["plot2"]]
|
||||
return ACTION_BY_ID[current["id"]]
|
||||
|
||||
|
||||
def plant_second_plot(world: dict, player: dict, action_id: str | None) -> str | None:
|
||||
"""Let a homesteader's second plot grow another crop, or clear it."""
|
||||
current = player["action"]
|
||||
if not action_id:
|
||||
if current:
|
||||
current.pop("plot2", None)
|
||||
current.pop("turn", None)
|
||||
return None
|
||||
if player["cls"] != "homesteader":
|
||||
return "Only homesteaders tend two plots"
|
||||
action = ACTION_BY_ID.get(action_id)
|
||||
if not action or action["skill"] != "farming" or action.get("special"):
|
||||
return "That isn't a crop"
|
||||
if not current or ACTION_BY_ID[current["id"]]["skill"] != "farming" or "left" in current:
|
||||
return "Plant your first plot first"
|
||||
if action_id == current["id"]:
|
||||
return "That's already growing in your first plot"
|
||||
reason = can_start(world, player, action)
|
||||
if reason:
|
||||
return reason
|
||||
current["plot2"] = action_id
|
||||
current["turn"] = 0
|
||||
return None
|
||||
|
||||
|
||||
def with_potion(blessed: dict, brew: dict) -> dict:
|
||||
"""A fight's prayer boosts with a combat potion's added on top."""
|
||||
return {**blessed, "power": blessed["power"] + brew.get("power", 0),
|
||||
|
|
@ -1295,9 +1384,13 @@ def process_player(world: dict, player: dict, now: float, rng: random.Random | N
|
|||
current = player["action"]
|
||||
if not current:
|
||||
return summary
|
||||
action = ACTION_BY_ID[current["id"]]
|
||||
limit = min(now, player["last_active"] + OFFLINE_CAP / speed(world))
|
||||
while player["action"]:
|
||||
action = growing(player)
|
||||
if current.get("plot2") and can_start(world, player, action):
|
||||
# The second crop can't grow right now (a problem, too low a level): tend the first only.
|
||||
current["turn"] = 0
|
||||
action = growing(player)
|
||||
duration = action_time(world, player, action)
|
||||
if current["start"] + duration > limit:
|
||||
break
|
||||
|
|
@ -1323,13 +1416,17 @@ def process_player(world: dict, player: dict, now: float, rng: random.Random | N
|
|||
_complete(world, player, action, current["start"] + duration, rng, summary)
|
||||
summary["done"] += 1
|
||||
current["start"] += duration
|
||||
if current.get("plot2"):
|
||||
current["turn"] = 1 - current.get("turn", 0)
|
||||
if player["action"] is current and "left" in current:
|
||||
current["left"] -= 1
|
||||
if current["left"] <= 0:
|
||||
back = current.get("resume")
|
||||
if back:
|
||||
plot2 = current.get("resume_plot2")
|
||||
player["action"] = current = {"id": back, "start": current["start"]}
|
||||
action = ACTION_BY_ID[back]
|
||||
if plot2:
|
||||
current.update(plot2=plot2, turn=0)
|
||||
summary["resumed"] = back
|
||||
else:
|
||||
stop(player)
|
||||
|
|
@ -1352,12 +1449,18 @@ def start_action(world: dict, player: dict, action_id: str, now: float, once: bo
|
|||
if reason:
|
||||
return reason
|
||||
entry = {"id": action_id, "start": now}
|
||||
current = player["action"]
|
||||
if once:
|
||||
current = player["action"]
|
||||
back = current and (current.get("resume") or current["id"])
|
||||
entry["left"] = 1
|
||||
if back and back != action_id:
|
||||
entry["resume"] = back
|
||||
plot2 = current.get("resume_plot2") or current.get("plot2")
|
||||
if plot2:
|
||||
entry["resume_plot2"] = plot2
|
||||
elif current and current.get("plot2") and current["plot2"] != action_id and action["skill"] == "farming":
|
||||
# Replanting the first plot leaves the second one growing.
|
||||
entry.update(plot2=current["plot2"], turn=0)
|
||||
player["action"] = entry
|
||||
player["stopped"] = None
|
||||
return None
|
||||
|
|
@ -2176,7 +2279,7 @@ ACTIONS.extend(PROBLEM_ACTIONS)
|
|||
ACTION_BY_ID.update({action["id"]: action for action in PROBLEM_ACTIONS})
|
||||
ITEMS["water_barrel"] = {"name": "Water barrel", "icon": "🛢️", "value": 20}
|
||||
_barrel = _action("cooper_barrel", "construction", "Water barrel", 10, 35, 18,
|
||||
{"oak_plank": 2, "iron_bar": 1}, {"water_barrel": 1}, group="Supplies")
|
||||
{"oak_plank": 2, "iron_nails": 4}, {"water_barrel": 1}, group="Supplies")
|
||||
ACTIONS.append(_barrel)
|
||||
ACTION_BY_ID[_barrel["id"]] = _barrel
|
||||
|
||||
|
|
@ -2185,29 +2288,29 @@ ACTION_BY_ID[_barrel["id"]] = _barrel
|
|||
# building stands; damage pauses it like the rest of the building.
|
||||
# id, name, building, building level, construction level, inputs, effect, glyph, tint
|
||||
FITTINGS = [
|
||||
("grain_bins", "Grain bins", "granary", 1, 15, {"oak_plank": 20, "iron_bar": 5},
|
||||
("grain_bins", "Grain bins", "granary", 1, 15, {"oak_plank": 20, "iron_nails": 25},
|
||||
"The city eats 10% less food", "grain-bundle", "#e3c060"),
|
||||
("saw_benches", "Saw benches", "lumber_shed", 1, 15, {"oak_plank": 20, "iron_bar": 10},
|
||||
("saw_benches", "Saw benches", "lumber_shed", 1, 15, {"oak_plank": 20, "iron_nails": 40},
|
||||
"Sawing planks is 20% faster", "hand-saw", "#8f5e30"),
|
||||
("shelving", "Shelving", "storehouse", 2, 20, {"oak_plank": 40, "iron_bar": 10},
|
||||
("shelving", "Shelving", "storehouse", 2, 20, {"oak_plank": 40, "iron_nails": 40},
|
||||
"+1 bank slot for everyone", "bookshelf", "#8f5e30"),
|
||||
("map_table", "Map table", "spymaster", 1, 30, {"willow_plank": 25, "hard_leather": 10},
|
||||
("map_table", "Map table", "spymaster", 1, 30, {"willow_plank": 25, "hard_leather": 10, "steel_hinges": 4},
|
||||
"Scouting gathers one more point of reconnaissance", "treasure-map", "#a3b86c"),
|
||||
("well_pump", "Well pump", "well", 2, 30, {"willow_plank": 25, "steel_bar": 10},
|
||||
("well_pump", "Well pump", "well", 2, 30, {"willow_plank": 25, "steel_hinges": 10},
|
||||
"Half of all fires are put out before they spread", "water-tank", "#5aa0d8"),
|
||||
("furniture", "Furniture", "houses", 2, 35, {"willow_plank": 40, "leather": 30},
|
||||
("furniture", "Furniture", "houses", 2, 35, {"willow_plank": 40, "leather": 30, "steel_hinges": 10},
|
||||
"Population grows 25% faster", "sofa", "#a3b86c"),
|
||||
("weapon_racks", "Weapon racks", "barracks", 2, 40, {"willow_plank": 30, "steel_bar": 20},
|
||||
("weapon_racks", "Weapon racks", "barracks", 2, 40, {"willow_plank": 30, "steel_hinges": 16},
|
||||
"Militia defence +50%", "spears", "#d4dae2"),
|
||||
("hoardings", "Hoardings", "walls", 3, 45, {"maple_plank": 40, "mithril_bar": 10},
|
||||
("hoardings", "Hoardings", "walls", 3, 45, {"maple_plank": 40, "mithril_brackets": 20},
|
||||
"+25 defence", "palisade", "#d0663a"),
|
||||
("bellows", "Great bellows", "smithy", 3, 50, {"maple_plank": 30, "bear_leather": 15},
|
||||
("bellows", "Great bellows", "smithy", 3, 50, {"maple_plank": 30, "bear_leather": 15, "mithril_brackets": 6},
|
||||
"Smithing another 10% faster", "bellows", "#d0663a"),
|
||||
("carved_altar", "Carved altar", "temple", 2, 60, {"yew_plank": 30, "cut_stone": 60},
|
||||
("carved_altar", "Carved altar", "temple", 2, 60, {"yew_plank": 30, "cut_stone": 60, "adamant_chain": 4},
|
||||
"+1 prayer point per bone buried, and offerings can ward 15 more", "star-altar", "#6f9a4a"),
|
||||
("enchanted_chests", "Enchanted chests", "storehouse", 4, 75, {"magic_plank": 40, "rune_bar": 5},
|
||||
("enchanted_chests", "Enchanted chests", "storehouse", 4, 75, {"magic_plank": 40, "rune_lock": 6},
|
||||
"+500 per bank stack for everyone", "open-treasure-chest", "#a77be8"),
|
||||
("enchanted_hearths", "Enchanted hearths", "houses", 4, 80, {"magic_plank": 50, "red_dragon_leather": 5},
|
||||
("enchanted_hearths", "Enchanted hearths", "houses", 4, 80, {"magic_plank": 50, "red_dragon_leather": 5, "adamant_chain": 6},
|
||||
"Everyone recovers HP twice as fast", "fireplace", "#a77be8"),
|
||||
]
|
||||
FITTING_BY_ID = {}
|
||||
|
|
@ -2785,6 +2888,7 @@ PIECE_GLYPHS = {"sword": "pointy-sword", "shield": "round-shield", "helmet": "vi
|
|||
TOOL_GLYPHS = {"pickaxe": "war-pick", "axe": "wood-axe", "hoe": "sickle", "fishing rod": "fishing-pole",
|
||||
"hunting knife": "bowie-knife", "hammer": "claw-hammer"}
|
||||
LEATHER_GLYPHS = {"cap": "hood", "legs": "trousers", "body": "leather-vest"}
|
||||
HARDWARE_GLYPHS = ["screw", "nails", "door-handle", "metal-plate", "crossed-chains", "padlock"]
|
||||
GLYPHS = {
|
||||
"stone": ("stone-block", "#a8a29e"), "wheat": ("wheat", "#e3c060"), "vegetables": ("carrot", "#f08a3c"),
|
||||
"feathers": ("feather", "#e8e8ee"), "raw_meat": ("meat", "#e06a6a"), "arrows": ("arrow-cluster", "#c9b28a"),
|
||||
|
|
@ -2804,7 +2908,7 @@ GLYPHS = {
|
|||
SKILL_GLYPHS = {
|
||||
"mining": ("mining", "#b8b2aa"), "woodcutting": ("wood-axe", "#c98a4a"), "farming": ("wheat", "#e3c060"),
|
||||
"hunting": ("deer-head", "#c49a6c"), "fishing": ("fishing-pole", "#5aa0d8"), "smithing": ("anvil", "#d07a3c"),
|
||||
"masonry": ("brick-wall", "#c66a45"), "construction": ("hammer-nails", "#d1a46a"),
|
||||
"construction": ("hammer-nails", "#d1a46a"),
|
||||
"cooking": ("cooking-pot", "#e0703a"), "leatherworking": ("sewing-needle", "#d6a26e"),
|
||||
"herblore": ("cauldron", "#7fbf5a"), "combat": ("crossed-swords", "#e05a5a"), "prayer": ("prayer", "#e9dfc6"),
|
||||
"reconnaissance": ("spyglass", "#6f8fec"),
|
||||
|
|
@ -2837,11 +2941,12 @@ UI_GLYPHS = ["two-coins", "sparkles", "hearts", "prayer", "checked-shield"]
|
|||
def _assign_glyphs() -> None:
|
||||
for item, (glyph, tint) in GLYPHS.items():
|
||||
ITEMS[item].update(glyph=glyph, tint=tint)
|
||||
for key, _name, ore, *_rest in METALS:
|
||||
for tier, (key, _name, ore, *_rest) in enumerate(METALS):
|
||||
tint = METAL_TINTS[key]
|
||||
if ore:
|
||||
ITEMS[ore[0]].update(glyph="ore", tint=tint)
|
||||
ITEMS[f"{key}_bar"].update(glyph="metal-bar", tint=tint)
|
||||
ITEMS[HARDWARE[tier][0]].update(glyph=HARDWARE_GLYPHS[tier], tint=tint)
|
||||
for piece, glyph in PIECE_GLYPHS.items():
|
||||
ITEMS[f"{key}_{piece}"].update(glyph=glyph, tint=tint)
|
||||
for tool, glyph in TOOL_GLYPHS.items():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue