feat(plants): Plant purchase system in Dave's Shop & pre-battle deck selection screen
This commit is contained in:
+24
-3
@@ -88,7 +88,14 @@ def get_default_profile_dict():
|
||||
"maxUnlockedLevel": 1,
|
||||
"highScore": 0,
|
||||
"theme": "classic",
|
||||
"upgrades": {"extraSlot": False, "hasRake": False},
|
||||
"upgrades": {
|
||||
"extraSlot": False,
|
||||
"hasRake": False,
|
||||
"unlockedPlants": ["sunflower", "peashooter", "wallnut"],
|
||||
"selectedDeck": ["sunflower", "peashooter", "wallnut"]
|
||||
},
|
||||
"unlockedPlants": ["sunflower", "peashooter", "wallnut"],
|
||||
"selectedDeck": ["sunflower", "peashooter", "wallnut"],
|
||||
"materials": {"bioHumus": 10, "scrapMetal": 5, "sunEssence": 20, "crystals": 0},
|
||||
"plantLevels": {"peashooter": 1, "sunflower": 1, "wallnut": 1, "potatomine": 1, "repeater": 1, "snowpea": 1, "chomper": 1},
|
||||
"perks": {"magnetism": 0, "startSun": 0, "fastCool": 0, "hardyRoots": 0, "luckyDrop": 0},
|
||||
@@ -199,13 +206,19 @@ def authenticate_user(username, password_hash):
|
||||
if not p:
|
||||
profile_dict = get_default_profile_dict()
|
||||
else:
|
||||
upg_data = json.loads(p["upgrades"] or "{}")
|
||||
unlocked_plants = upg_data.get("unlockedPlants", ["sunflower", "peashooter", "wallnut"])
|
||||
selected_deck = upg_data.get("selectedDeck", ["sunflower", "peashooter", "wallnut"])
|
||||
|
||||
profile_dict = {
|
||||
"coins": p["coins"],
|
||||
"level": p["level"],
|
||||
"maxUnlockedLevel": p["max_unlocked_level"],
|
||||
"highScore": p["high_score"],
|
||||
"theme": p["theme"],
|
||||
"upgrades": json.loads(p["upgrades"] or "{}"),
|
||||
"upgrades": upg_data,
|
||||
"unlockedPlants": unlocked_plants,
|
||||
"selectedDeck": selected_deck,
|
||||
"materials": json.loads(p["materials"] or "{}"),
|
||||
"plantLevels": json.loads(p["plant_levels"] or "{}"),
|
||||
"perks": json.loads(p["perks"] or "{}"),
|
||||
@@ -247,7 +260,15 @@ def save_user_profile(username, data):
|
||||
cur_obj.update(new_val)
|
||||
return json.dumps(cur_obj)
|
||||
|
||||
upgrades_json = merge_json("upgrades", {})
|
||||
upg_obj = json.loads(current["upgrades"] or "{}") if current and current["upgrades"] else {}
|
||||
if "upgrades" in data and isinstance(data["upgrades"], dict):
|
||||
upg_obj.update(data["upgrades"])
|
||||
if "unlockedPlants" in data and isinstance(data["unlockedPlants"], list):
|
||||
upg_obj["unlockedPlants"] = data["unlockedPlants"]
|
||||
if "selectedDeck" in data and isinstance(data["selectedDeck"], list):
|
||||
upg_obj["selectedDeck"] = data["selectedDeck"]
|
||||
upgrades_json = json.dumps(upg_obj)
|
||||
|
||||
materials_json = merge_json("materials", {})
|
||||
plant_levels_json = merge_json("plant_levels", {}) if "plant_levels" in data else (json.dumps(data["plantLevels"]) if "plantLevels" in data else (current["plant_levels"] if current else "{}"))
|
||||
perks_json = merge_json("perks", {})
|
||||
|
||||
@@ -736,6 +736,54 @@ def test_http_endpoint():
|
||||
except Exception as e:
|
||||
record(f"HTTP {name} ({url})", "FAIL", str(e))
|
||||
|
||||
def test_plant_shop_and_deck_selection():
|
||||
print("\n--- 11b. Plant Shop, Locked Plants & Pre-Battle Deck Selection ---")
|
||||
econ_path = os.path.join(GAME_DIR, "js/systems/economy.js")
|
||||
with open(econ_path, "r", encoding="utf-8") as f:
|
||||
econ_code = f.read()
|
||||
|
||||
record("PLANT_CATALOGUE defined in economy.js", "PASS" if "window.PLANT_CATALOGUE" in econ_code else "FAIL")
|
||||
record("Sunflower default unlocked in PLANT_CATALOGUE", "PASS" if "id: 'sunflower'" in econ_code and "defaultUnlocked: true" in econ_code else "FAIL")
|
||||
record("Peashooter default unlocked in PLANT_CATALOGUE", "PASS" if "id: 'peashooter'" in econ_code and "defaultUnlocked: true" in econ_code else "FAIL")
|
||||
record("Wallnut default unlocked in PLANT_CATALOGUE", "PASS" if "id: 'wallnut'" in econ_code and "defaultUnlocked: true" in econ_code else "FAIL")
|
||||
record("PotatoMine locked by default with price", "PASS" if "id: 'potatomine'" in econ_code and "price: 150" in econ_code and "defaultUnlocked: false" in econ_code else "FAIL")
|
||||
record("Melonpult locked by default with price", "PASS" if "id: 'melonpult'" in econ_code and "price: 750" in econ_code and "defaultUnlocked: false" in econ_code else "FAIL")
|
||||
|
||||
econ_methods = [
|
||||
"isPlantUnlocked",
|
||||
"buyPlant",
|
||||
"addToDeck",
|
||||
"removeFromDeck",
|
||||
"autoFillDeck",
|
||||
"setDeckFromSelection",
|
||||
"getMaxSlots"
|
||||
]
|
||||
for m in econ_methods:
|
||||
if m in econ_code:
|
||||
record(f"EconomySystem.{m} method implemented", "PASS")
|
||||
else:
|
||||
record(f"EconomySystem.{m} method implemented", "FAIL", f"Missing {m}")
|
||||
|
||||
index_html_path = os.path.join(GAME_DIR, "index.html")
|
||||
with open(index_html_path, "r", encoding="utf-8") as f:
|
||||
html_code = f.read()
|
||||
|
||||
record("Shop plants grid present in HTML", "PASS" if 'id="shop-plants-grid"' in html_code else "FAIL")
|
||||
record("Pre-battle seed select modal present in HTML", "PASS" if 'id="seed-select-modal"' in html_code else "FAIL")
|
||||
record("Seed active deck container present in HTML", "PASS" if 'id="seed-active-deck"' in html_code else "FAIL")
|
||||
record("Seed inventory grid container present in HTML", "PASS" if 'id="seed-inventory-grid"' in html_code else "FAIL")
|
||||
record("Start battle button in seed select modal present", "PASS" if 'id="btn-seed-start-battle"' in html_code else "FAIL")
|
||||
record("Auto-fill button in seed select modal present", "PASS" if 'id="btn-seed-auto-fill"' in html_code else "FAIL")
|
||||
record("Inventory start button on main menu present", "PASS" if 'id="btn-inventory-start"' in html_code else "FAIL")
|
||||
|
||||
game_js_path = os.path.join(GAME_DIR, "js/game.js")
|
||||
with open(game_js_path, "r", encoding="utf-8") as f:
|
||||
game_code = f.read()
|
||||
|
||||
record("GameEngine.openSeedSelectionModal implemented", "PASS" if "openSeedSelectionModal(" in game_code else "FAIL")
|
||||
record("GameEngine.renderSeedSelectionUI implemented", "PASS" if "renderSeedSelectionUI(" in game_code else "FAIL")
|
||||
record("Shop plants nursery population implemented in updateShopUI", "PASS" if "shop-plants-grid" in game_code and "PLANT_CATALOGUE" in game_code else "FAIL")
|
||||
|
||||
def main():
|
||||
print("==================================================")
|
||||
print("🌱 PLANTS VS. ZOMBIES — AUTONOMOUS TEST SUITE 🌱")
|
||||
@@ -752,6 +800,7 @@ def main():
|
||||
test_v2_1_features()
|
||||
test_campaign_system()
|
||||
test_feedback_and_layout_system()
|
||||
test_plant_shop_and_deck_selection()
|
||||
test_http_endpoint()
|
||||
|
||||
passed = sum(1 for r in TEST_RESULTS if r["status"] == "PASS")
|
||||
|
||||
Reference in New Issue
Block a user