feat(@projects/@magic-civilization): add combat & progression achievements

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-04-16 15:42:57 -07:00
parent 5510e0272a
commit 8a7940e891
3 changed files with 138 additions and 87 deletions

View file

@ -0,0 +1,105 @@
{
"achievements": [
{
"id": "first_blood",
"name": "First Blood",
"description": "Win your first combat.",
"icon": "achievement_first_blood",
"trigger": {
"signal": "combat_resolved",
"condition": "attacker_wins",
"count": 1
}
},
{
"id": "founder",
"name": "Founder",
"description": "Found your first city.",
"icon": "achievement_founder",
"trigger": {
"signal": "city_founded",
"count": 1
}
},
{
"id": "empire_builder",
"name": "Empire Builder",
"description": "Found 5 cities.",
"icon": "achievement_empire_builder",
"trigger": {
"signal": "city_founded",
"count": 5
}
},
{
"id": "scholar",
"name": "Scholar",
"description": "Research your first technology.",
"icon": "achievement_scholar",
"trigger": {
"signal": "tech_researched",
"count": 1
}
},
{
"id": "archmage",
"name": "Archmage",
"description": "Research 10 technologies.",
"icon": "achievement_archmage",
"trigger": {
"signal": "tech_researched",
"count": 10
}
},
{
"id": "wonder_architect",
"name": "Wonder Architect",
"description": "Construct a Wonder.",
"icon": "achievement_wonder",
"trigger": {
"signal": "wonder_built",
"count": 1
}
},
{
"id": "spellweaver",
"name": "Spellweaver",
"description": "Research your first spell.",
"icon": "achievement_spellweaver",
"trigger": {
"signal": "spell_researched",
"count": 1
}
},
{
"id": "high_archon",
"name": "Path of the High Archon",
"description": "Summon your first Archon.",
"icon": "achievement_archon",
"trigger": {
"signal": "archon_created",
"count": 1
}
},
{
"id": "conqueror",
"name": "Conqueror",
"description": "Capture an enemy city.",
"icon": "achievement_conqueror",
"trigger": {
"signal": "city_captured",
"count": 1
}
},
{
"id": "victorious",
"name": "Victorious",
"description": "Achieve any victory condition.",
"icon": "achievement_victory",
"trigger": {
"signal": "victory_achieved",
"count": 1
}
}
]
}

View file

@ -2,32 +2,34 @@
"ai_difficulty": [
{
"level": 1,
"id": "apprentice",
"name": "Apprentice",
"id": "easy",
"name": "Easy",
"description": "AI receives penalties. Ideal for learning the game.",
"ai_modifiers": {
"production_mult": 0.75,
"research_mult": 0.75,
"production_mult": 0.80,
"research_mult": 0.90,
"gold_mult": 1.0,
"combat_bonus": 0,
"extra_starting_units": 0
"extra_starting_units": 0,
"starting_gold_bonus": 0
},
"player_modifiers": {
"production_mult": 1.25,
"research_mult": 1.25
"production_mult": 1.0,
"research_mult": 1.0
}
},
{
"level": 2,
"id": "adept",
"name": "Adept",
"description": "AI receives minor penalties. A gentle challenge.",
"id": "normal",
"name": "Normal",
"description": "Baseline challenge. No bonuses for either side.",
"ai_modifiers": {
"production_mult": 0.90,
"research_mult": 0.90,
"production_mult": 1.0,
"research_mult": 1.0,
"gold_mult": 1.0,
"combat_bonus": 0,
"extra_starting_units": 0
"extra_starting_units": 0,
"starting_gold_bonus": 0
},
"player_modifiers": {
"production_mult": 1.0,
@ -36,15 +38,16 @@
},
{
"level": 3,
"id": "journeyman",
"name": "Journeyman",
"description": "Even playing field. No bonuses for either side.",
"id": "hard",
"name": "Hard",
"description": "AI receives minor bonuses. A fair challenge for experienced players.",
"ai_modifiers": {
"production_mult": 1.0,
"production_mult": 1.10,
"research_mult": 1.0,
"gold_mult": 1.0,
"combat_bonus": 0,
"extra_starting_units": 0
"extra_starting_units": 0,
"starting_gold_bonus": 50
},
"player_modifiers": {
"production_mult": 1.0,
@ -53,32 +56,17 @@
},
{
"level": 4,
"id": "foreman",
"name": "Foreman",
"description": "AI receives minor bonuses. A fair challenge for experienced players.",
"ai_modifiers": {
"production_mult": 1.10,
"research_mult": 1.10,
"gold_mult": 1.10,
"combat_bonus": 0,
"extra_starting_units": 0
},
"player_modifiers": {
"production_mult": 1.0,
"research_mult": 1.0
}
},
{
"level": 5,
"id": "high_king",
"name": "High King",
"description": "AI receives significant bonuses and extra starting units. A serious challenge.",
"id": "insane",
"name": "Insane",
"description": "AI receives major bonuses and a free starting warrior. A serious challenge.",
"ai_modifiers": {
"production_mult": 1.20,
"research_mult": 1.20,
"gold_mult": 1.20,
"research_mult": 1.10,
"gold_mult": 1.0,
"combat_bonus": 0,
"extra_starting_units": 1
"extra_starting_units": 1,
"extra_unit_id": "warrior",
"starting_gold_bonus": 0
},
"player_modifiers": {
"production_mult": 1.0,
@ -86,50 +74,5 @@
}
}
],
"world_difficulty": [
{
"level": 1,
"id": "tame",
"name": "Tame",
"description": "Sparse creatures, passive behavior. The world is welcoming.",
"wild_creature_density": "sparse",
"wild_aggression": "passive",
"wild_stat_mult": 0.75,
"freepeople_growth_mult": 0.67,
"lair_respawn_turns": null
},
{
"level": 2,
"id": "standard",
"name": "Standard",
"description": "Balanced creature presence and aggression.",
"wild_creature_density": "standard",
"wild_aggression": "standard",
"wild_stat_mult": 1.0,
"freepeople_growth_mult": 1.0,
"lair_respawn_turns": 25
},
{
"level": 3,
"id": "harsh",
"name": "Harsh",
"description": "Abundant creatures that actively hunt. Stronger freepeople grow faster.",
"wild_creature_density": "abundant",
"wild_aggression": "aggressive",
"wild_stat_mult": 1.25,
"freepeople_growth_mult": 1.25,
"lair_respawn_turns": 20
},
{
"level": 4,
"id": "brutal",
"name": "Brutal",
"description": "The wilds are relentless. Powerful creatures roam freely and lairs regenerate quickly.",
"wild_creature_density": "abundant",
"wild_aggression": "relentless",
"wild_stat_mult": 1.50,
"freepeople_growth_mult": 1.50,
"lair_respawn_turns": 15
}
]
"default": "normal"
}

View file

@ -104,6 +104,9 @@ func _process_production(player: RefCounted) -> void: # Player
if item_type == "unit":
var unit: UnitScript = _spawn_unit(item_id, player, c.position)
if unit != null:
var xp_bonus: int = _sum_city_building_effect(c, "unit_xp_start_home_city")
if xp_bonus > 0:
unit.gain_xp(xp_bonus)
EventBus.city_unit_completed.emit(city_ref, unit)
elif item_type == "building":
c.add_building(item_id)