diff --git a/public/resources/wilds/wilds.json b/public/resources/wilds/wilds.json index c519f162..94f4757a 100644 --- a/public/resources/wilds/wilds.json +++ b/public/resources/wilds/wilds.json @@ -140,6 +140,161 @@ { "level": "harsh", "spawn_interval_mult": 0.75, "max_creatures": 4, "stat_mult": 1.25, "new_lair_interval": 20 }, { "level": "brutal", "spawn_interval_mult": 0.5, "max_creatures": 5, "stat_mult": 1.5, "new_lair_interval": 15 } ], + "creature_loot": { + "beast_den": { + "id": "beast_den", + "loot_table": [ + { "resource": "hide", "amount": 2, "chance": 0.8 }, + { "resource": "bone", "amount": 2, "chance": 0.6 }, + { "resource": "fang", "amount": 1, "chance": 0.4 } + ] + }, + "corrupted_hollow": { + "id": "corrupted_hollow", + "loot_table": [ + { "resource": "death_essence", "amount": 2, "chance": 0.7 }, + { "resource": "spectral_shard", "amount": 1, "chance": 0.4 } + ] + }, + "volcanic_fissure": { + "id": "volcanic_fissure", + "loot_table": [ + { "resource": "fire_essence", "amount": 2, "chance": 0.7 }, + { "resource": "obsidian", "amount": 1, "chance": 0.5 } + ] + }, + "ancient_construct_site": { + "id": "ancient_construct_site", + "loot_table": [ + { "resource": "arcane_gears", "amount": 2, "chance": 0.8 }, + { "resource": "stone_core", "amount": 1, "chance": 0.5 } + ] + }, + "wyvern_nest": { + "id": "wyvern_nest", + "loot_table": [ + { "resource": "wyvern_scale", "amount": 2, "chance": 0.8 }, + { "resource": "bone", "amount": 2, "chance": 0.5 } + ] + }, + "wolf_pack": { + "id": "wolf_pack", + "loot_table": [ + { "resource": "hide", "amount": 1, "chance": 0.6 }, + { "resource": "bone", "amount": 1, "chance": 0.4 } + ] + }, + "feral_spider": { + "id": "feral_spider", + "loot_table": [ + { "resource": "spider_silk", "amount": 1, "chance": 0.5 }, + { "resource": "venom_gland", "amount": 1, "chance": 0.3 } + ] + }, + "dire_bear": { + "id": "dire_bear", + "loot_table": [ + { "resource": "thick_hide", "amount": 2, "chance": 0.7 }, + { "resource": "bone", "amount": 2, "chance": 0.5 } + ] + }, + "basilisk_wild": { + "id": "basilisk_wild", + "loot_table": [ + { "resource": "basilisk_eye", "amount": 1, "chance": 0.4 }, + { "resource": "scale", "amount": 2, "chance": 0.6 } + ] + }, + "ancient_hydra": { + "id": "ancient_hydra", + "loot_table": [ + { "resource": "hydra_blood", "amount": 2, "chance": 0.6 }, + { "resource": "scale", "amount": 3, "chance": 0.8 } + ] + }, + "shambling_dead": { + "id": "shambling_dead", + "loot_table": [ + { "resource": "death_essence", "amount": 1, "chance": 0.5 } + ] + }, + "spectral_knight": { + "id": "spectral_knight", + "loot_table": [ + { "resource": "death_essence", "amount": 2, "chance": 0.6 }, + { "resource": "spectral_shard", "amount": 1, "chance": 0.3 } + ] + }, + "lich_wild": { + "id": "lich_wild", + "loot_table": [ + { "resource": "death_essence", "amount": 3, "chance": 0.8 }, + { "resource": "phylactery_fragment", "amount": 1, "chance": 0.2 } + ] + }, + "fire_imp": { + "id": "fire_imp", + "loot_table": [ + { "resource": "fire_essence", "amount": 1, "chance": 0.5 } + ] + }, + "lava_elemental": { + "id": "lava_elemental", + "loot_table": [ + { "resource": "fire_essence", "amount": 2, "chance": 0.7 }, + { "resource": "magma_core", "amount": 1, "chance": 0.3 } + ] + }, + "infernal_wild": { + "id": "infernal_wild", + "loot_table": [ + { "resource": "fire_essence", "amount": 3, "chance": 0.8 }, + { "resource": "infernal_shard", "amount": 1, "chance": 0.25 } + ] + }, + "stone_sentinel": { + "id": "stone_sentinel", + "loot_table": [ + { "resource": "arcane_gears", "amount": 1, "chance": 0.5 }, + { "resource": "stone_core", "amount": 1, "chance": 0.4 } + ] + }, + "iron_golem_wild": { + "id": "iron_golem_wild", + "loot_table": [ + { "resource": "arcane_gears", "amount": 2, "chance": 0.6 }, + { "resource": "iron_plating", "amount": 1, "chance": 0.5 } + ] + }, + "adamantine_colossus": { + "id": "adamantine_colossus", + "loot_table": [ + { "resource": "arcane_gears", "amount": 3, "chance": 0.8 }, + { "resource": "adamantine_shard", "amount": 1, "chance": 0.2 } + ] + }, + "wild_wyvern": { + "id": "wild_wyvern", + "loot_table": [ + { "resource": "wyvern_scale", "amount": 1, "chance": 0.6 }, + { "resource": "bone", "amount": 1, "chance": 0.4 } + ] + }, + "drake_wild": { + "id": "drake_wild", + "loot_table": [ + { "resource": "drake_fang", "amount": 1, "chance": 0.5 }, + { "resource": "wyvern_scale", "amount": 2, "chance": 0.7 } + ] + }, + "elder_wyrm": { + "id": "elder_wyrm", + "loot_table": [ + { "resource": "wyrm_heart", "amount": 1, "chance": 0.3 }, + { "resource": "wyvern_scale", "amount": 3, "chance": 0.9 } + ] + } + }, "aggression_settings": { "passive": { "guardian_roams": false, "detection_radius": 0, "attacks": false }, "standard": { "guardian_roams": true, "detection_radius": 4, "attacks": true, "suicide_check": true }, diff --git a/src/game/engine/scenes/city/city_buildable_helper.gd b/src/game/engine/scenes/city/city_buildable_helper.gd index 0a218e05..56c3b644 100644 --- a/src/game/engine/scenes/city/city_buildable_helper.gd +++ b/src/game/engine/scenes/city/city_buildable_helper.gd @@ -33,6 +33,21 @@ static func populate_buildings( ) +## Return true when any tile owned by `player`'s cities contains `resource_id`. +static func player_owns_resource(player: RefCounted, resource_id: String) -> bool: + if resource_id == "" or player == null: + return true + var gm: RefCounted = GameState.get_game_map() + if gm == null: + return false + for city: Variant in player.cities: + for tile_pos: Variant in city.get_owned_tiles(): + var tile: RefCounted = gm.get_tile(tile_pos as Vector2i) + if tile != null and tile.resource_id == resource_id: + return true + return false + + ## Populate `list` with the units the city can currently train. ## Items get metadata `{type: "unit", id: }`. static func populate_units( @@ -47,6 +62,9 @@ static func populate_units( continue if has_can_build and not city.can_build(uid, player): continue + var req_res: String = str(udata.get("requires_resource", "")) + if req_res != "" and req_res != "null" and not player_owns_resource(player, req_res): + continue var display: String = FormatterScript.resolve_display_name(udata, uid) var cost: int = udata.get("cost", 0) list.add_item("%s (%d)" % [display, cost]) diff --git a/src/simulator/crates/mc-city/src/city.rs b/src/simulator/crates/mc-city/src/city.rs index 1065967a..5754af3b 100644 --- a/src/simulator/crates/mc-city/src/city.rs +++ b/src/simulator/crates/mc-city/src/city.rs @@ -481,10 +481,10 @@ impl City { self.hp = (self.hp + amount).min(self.max_hp); } - /// Heal the city by the standard per-turn amount (20 HP). + /// Heal the city by the standard per-turn amount (10 HP). /// Skips destroyed cities (HP == 0). pub fn heal_per_turn(&mut self) { - const HEAL_PER_TURN: u32 = 20; + const HEAL_PER_TURN: u32 = 10; if self.hp > 0 && self.hp < self.max_hp { self.heal(HEAL_PER_TURN); }