Crafting always adds worth: hardware rounds up, planks, provisions, barrels, fittings +20%
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3df9f29b1d
commit
4e54c65503
2 changed files with 16 additions and 15 deletions
17
game.py
17
game.py
|
|
@ -22,6 +22,7 @@ BASE_STACK = 1000
|
||||||
CLASS_SPEED = 0.8
|
CLASS_SPEED = 0.8
|
||||||
LUCKY_CHANCE = 0.1
|
LUCKY_CHANCE = 0.1
|
||||||
OVERFLOW_FAVOUR = 0.5 # favour for items a full bank spills to the city, vs. giving on purpose
|
OVERFLOW_FAVOUR = 0.5 # favour for items a full bank spills to the city, vs. giving on purpose
|
||||||
|
CRAFT_MARKUP = 1.2 # what making something adds to the worth of its materials
|
||||||
MAX_LOG = 200
|
MAX_LOG = 200
|
||||||
PLAYER_LOG = 60 # lines in each player's own ledger
|
PLAYER_LOG = 60 # lines in each player's own ledger
|
||||||
REGEN_PER_HOUR = 0.25 # share of max HP recovered per game hour
|
REGEN_PER_HOUR = 0.25 # share of max HP recovered per game hour
|
||||||
|
|
@ -79,7 +80,7 @@ ITEMS = {
|
||||||
"flax": {"name": "Flax", "icon": "🌿", "value": 2},
|
"flax": {"name": "Flax", "icon": "🌿", "value": 2},
|
||||||
"rope": {"name": "Rope", "icon": "🪢", "value": 8},
|
"rope": {"name": "Rope", "icon": "🪢", "value": 8},
|
||||||
"hide_glue": {"name": "Hide glue", "icon": "🍯", "value": 7},
|
"hide_glue": {"name": "Hide glue", "icon": "🍯", "value": 7},
|
||||||
"provisions": {"name": "Provisions", "icon": "🎒", "value": 10},
|
"provisions": {"name": "Provisions", "icon": "🎒", "value": 12},
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- tier ladders -----------------------------------------------------------
|
# --- tier ladders -----------------------------------------------------------
|
||||||
|
|
@ -343,13 +344,13 @@ HARDWARE = [
|
||||||
("rune_lock", "Rune lock", "Rune locks", 2, 1),
|
("rune_lock", "Rune lock", "Rune locks", 2, 1),
|
||||||
]
|
]
|
||||||
for (_id, _name, _plural, _bars, _made), _metal in zip(HARDWARE, METALS):
|
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)),
|
ITEMS[_id] = {"name": _name, "plural": _plural, "icon": "🔩", "value": math.ceil(round(_bars * _metal[5] * CRAFT_MARKUP / _made, 6)),
|
||||||
"tier": METALS.index(_metal)}
|
"tier": METALS.index(_metal)}
|
||||||
PLANKS = [("plank", "Plank"), ("oak_plank", "Oak plank"), ("willow_plank", "Willow plank"),
|
PLANKS = [("plank", "Plank"), ("oak_plank", "Oak plank"), ("willow_plank", "Willow plank"),
|
||||||
("maple_plank", "Maple plank"), ("yew_plank", "Yew plank"), ("magic_plank", "Enchanted 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):
|
for (_log, _name, _icon, _value, _action_id, _verb), (_plank, _plank_name) in zip(TREES, PLANKS):
|
||||||
ITEMS[_log] = {"name": _name, "icon": _icon, "value": _value}
|
ITEMS[_log] = {"name": _name, "icon": _icon, "value": _value}
|
||||||
ITEMS[_plank] = {"name": _plank_name, "icon": "🪚", "value": _value * 2 + 1}
|
ITEMS[_plank] = {"name": _plank_name, "icon": "🪚", "value": round(_value * 2 * CRAFT_MARKUP) + 1}
|
||||||
# Weapons: four styles, one per trade. The sword pairs with a shield; the
|
# Weapons: four styles, one per trade. The sword pairs with a shield; the
|
||||||
# warhammer, staff and bow take both hands, so they carry the shield's power too.
|
# warhammer, staff and bow take both hands, so they carry the shield's power too.
|
||||||
SWORD_POWER = next(piece[5] for piece in PIECES if piece[0] == "sword")
|
SWORD_POWER = next(piece[5] for piece in PIECES if piece[0] == "sword")
|
||||||
|
|
@ -5421,9 +5422,10 @@ PROBLEM_ACTIONS = [
|
||||||
]
|
]
|
||||||
ACTIONS.extend(PROBLEM_ACTIONS)
|
ACTIONS.extend(PROBLEM_ACTIONS)
|
||||||
ACTION_BY_ID.update({action["id"]: action for action in 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,
|
_barrel = _action("cooper_barrel", "construction", "Water barrel", 10, 35, 18,
|
||||||
{"oak_plank": 2, "iron_nails": 4}, {"water_barrel": 1}, group="Supplies")
|
{"oak_plank": 2, "iron_nails": 4}, {"water_barrel": 1}, group="Supplies")
|
||||||
|
ITEMS["water_barrel"] = {"name": "Water barrel", "icon": "🛢️",
|
||||||
|
"value": round(sum(ITEMS[i]["value"] * q for i, q in _barrel["inputs"].items()) * CRAFT_MARKUP)}
|
||||||
ACTIONS.append(_barrel)
|
ACTIONS.append(_barrel)
|
||||||
ACTION_BY_ID[_barrel["id"]] = _barrel
|
ACTION_BY_ID[_barrel["id"]] = _barrel
|
||||||
|
|
||||||
|
|
@ -5466,18 +5468,17 @@ for _jewel in [*_jewel_actions(), *_storage_actions()]:
|
||||||
ACTION_BY_ID[_jewel["id"]] = _jewel
|
ACTION_BY_ID[_jewel["id"]] = _jewel
|
||||||
# Gear and guard kit are worth everything that went into them, trophies and reagents
|
# Gear and guard kit are worth everything that went into them, trophies and reagents
|
||||||
# included, so crafting one never loses its maker favour or gold.
|
# included, so crafting one never loses its maker favour or gold.
|
||||||
GEAR_MARKUP = 1.2
|
|
||||||
for _craft in ACTIONS:
|
for _craft in ACTIONS:
|
||||||
_made = next(iter(_craft["outputs"]), None)
|
_made = next(iter(_craft["outputs"]), None)
|
||||||
if _made in ITEMS and (ITEMS[_made].get("slot") in ("weapon", "shield", "helmet", "body", "legs")
|
if _made in ITEMS and (ITEMS[_made].get("slot") in ("weapon", "shield", "helmet", "body", "legs")
|
||||||
or "kit" in ITEMS[_made]):
|
or "kit" in ITEMS[_made]):
|
||||||
ITEMS[_made]["value"] = round(sum(ITEMS[i]["value"] * q for i, q in _craft["inputs"].items()) * GEAR_MARKUP)
|
ITEMS[_made]["value"] = round(sum(ITEMS[i]["value"] * q for i, q in _craft["inputs"].items()) * CRAFT_MARKUP)
|
||||||
_dungeon_loot() # masterworks are reforged from all of the above
|
_dungeon_loot() # masterworks are reforged from all of the above
|
||||||
FITTING_BY_ID = {}
|
FITTING_BY_ID = {}
|
||||||
for _id, _name, _building, _blevel, _level, _inputs, _effect, _glyph, _tint in FITTINGS:
|
for _id, _name, _building, _blevel, _level, _inputs, _effect, _glyph, _tint in FITTINGS:
|
||||||
FITTING_BY_ID[_id] = {"id": _id, "name": _name, "building": _building, "level": _blevel, "effect": _effect}
|
FITTING_BY_ID[_id] = {"id": _id, "name": _name, "building": _building, "level": _blevel, "effect": _effect}
|
||||||
ITEMS[_id] = {"name": _name, "plural": _name, "icon": "🪚", "value": sum(ITEMS[i]["value"] * q for i, q in _inputs.items()),
|
ITEMS[_id] = {"name": _name, "plural": _name, "icon": "🪚", "fitting": _building,
|
||||||
"fitting": _building}
|
"value": round(sum(ITEMS[i]["value"] * q for i, q in _inputs.items()) * CRAFT_MARKUP)}
|
||||||
_fitting = _action(f"make_{_id}", "construction", _name, _level, 120 + _level * 2, 40 + _level * 4,
|
_fitting = _action(f"make_{_id}", "construction", _name, _level, 120 + _level * 2, 40 + _level * 4,
|
||||||
_inputs, {_id: 1}, group="Fittings")
|
_inputs, {_id: 1}, group="Fittings")
|
||||||
ACTIONS.append(_fitting)
|
ACTIONS.append(_fitting)
|
||||||
|
|
|
||||||
|
|
@ -2697,10 +2697,10 @@ class WorkOrderTest(unittest.TestCase):
|
||||||
self.fred["bank"] = {"oak_plank": 1, "clay_core": 3}
|
self.fred["bank"] = {"oak_plank": 1, "clay_core": 3}
|
||||||
self.assertIsNone(game.work_order(self.world, self.fred, order["id"], T0))
|
self.assertIsNone(game.work_order(self.world, self.fred, order["id"], T0))
|
||||||
game.process_player(self.world, self.fred, T0 + 600, random.Random(1))
|
game.process_player(self.world, self.fred, T0 + 600, random.Random(1))
|
||||||
# Reagents are worth 84 a run; Dave's 2 bars (20) earn 20/84 of half the reward.
|
# Reagents are worth 86 a run; Dave's 2 bars (20) earn 20/86 of half the reward.
|
||||||
self.assertEqual(self.dave["gold"], 17)
|
self.assertEqual(self.dave["gold"], 16)
|
||||||
self.assertEqual(self.fred["gold"], 123) # the requester's own bar leaves its share with the crafter
|
self.assertEqual(self.fred["gold"], 124) # the requester's own bar leaves its share with the crafter
|
||||||
self.assertEqual(order["earned"], {"dave": 17})
|
self.assertEqual(order["earned"], {"dave": 16})
|
||||||
|
|
||||||
def test_crafter_tops_up_a_short_pool(self):
|
def test_crafter_tops_up_a_short_pool(self):
|
||||||
self.mike["gold"] = 200
|
self.mike["gold"] = 200
|
||||||
|
|
@ -2750,9 +2750,9 @@ class WorkOrderTest(unittest.TestCase):
|
||||||
self.assertEqual(order["status"], "done")
|
self.assertEqual(order["status"], "done")
|
||||||
self.assertEqual(self.world["city"]["stockpile"].get("iron_warhammer"), 1)
|
self.assertEqual(self.world["city"]["stockpile"].get("iron_warhammer"), 1)
|
||||||
self.assertEqual(self.fred["bank"], {})
|
self.assertEqual(self.fred["bank"], {})
|
||||||
# Hammer 101: Dave's bars 20 and Mike's cores 45 as if donated, Fred the other 36.
|
# Hammer 103: Dave's bars 20 and Mike's cores 45 as if donated, Fred the other 38.
|
||||||
self.assertEqual(order["favour"], {"dave": 20, "mike": 45, "fred": 36})
|
self.assertEqual(order["favour"], {"dave": 20, "mike": 45, "fred": 38})
|
||||||
self.assertEqual((self.dave["favour"], self.mike["favour"], self.fred["favour"]), (20, 45, 36))
|
self.assertEqual((self.dave["favour"], self.mike["favour"], self.fred["favour"]), (20, 45, 38))
|
||||||
line = self.mike["ledger"][-1]
|
line = self.mike["ledger"][-1]
|
||||||
self.assertEqual((line["verb"], line["item"], line["qty"], line["label"]), ("Donated", "clay_core", 3, "City order"))
|
self.assertEqual((line["verb"], line["item"], line["qty"], line["label"]), ("Donated", "clay_core", 3, "City order"))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue