Compare commits
19 Commits
a5ab466df9
...
master
Author | SHA1 | Date | |
---|---|---|---|
f81a237f01 | |||
47281a098d | |||
5dd8e6fff9 | |||
0747595f2b | |||
2bf0f4a360 | |||
bdcc0d5089 | |||
1b3657b03a | |||
6d8139fd44 | |||
cdd944b9b5 | |||
c0d18507e3 | |||
7e8ccb061a | |||
e7247ee715 | |||
048688da45 | |||
3d48d7e9d6 | |||
33c182e623 | |||
4ceb63e49c | |||
0fbd49f36a | |||
8ae0e7e80c | |||
73a89b736e |
15
Dialogue/tutorial.dialogue
Normal file
15
Dialogue/tutorial.dialogue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
~ start
|
||||||
|
Narrator: You are a newborn god, a consciousness adrift in the cosmos.
|
||||||
|
|
||||||
|
Narrator: Below you, a nascent world teems with life. A small tribe of followers has begun to worship you. Their belief is your existence.
|
||||||
|
|
||||||
|
Narrator: Your goal is simple: nurture this civilization until they can reach for the stars and carry you with them.
|
||||||
|
|
||||||
|
Narrator: Grant them miracles to grow their population and advance their industry. Click the buttons on the right to see your powers.
|
||||||
|
|
||||||
|
Narrator: But be warned... your divine presence is a paradox. Every miracle that helps your followers also poisons their world, corrupting it.
|
||||||
|
|
||||||
|
Narrator: If the world's corruption reaches 100%, it will be consumed, and you along with it.
|
||||||
|
|
||||||
|
Narrator: Guide them. Grow them. But do not destroy them before they can escape. Their fate, and yours, is in your hands.
|
||||||
|
=> END
|
16
Dialogue/tutorial.dialogue.import
Normal file
16
Dialogue/tutorial.dialogue.import
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="dialogue_manager"
|
||||||
|
importer_version=15
|
||||||
|
type="Resource"
|
||||||
|
uid="uid://dxgpvgx7axp88"
|
||||||
|
path="res://.godot/imported/tutorial.dialogue-20e92c929aa826a6ba83a2adbbdba7f9.tres"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Dialogue/tutorial.dialogue"
|
||||||
|
dest_files=["res://.godot/imported/tutorial.dialogue-20e92c929aa826a6ba83a2adbbdba7f9.tres"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
defaults=true
|
37
Mods/Events/a_plague_descends.json
Normal file
37
Mods/Events/a_plague_descends.json
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"id": "event_plague_descends",
|
||||||
|
"title": "A Plague Descends",
|
||||||
|
"description": "A virulent disease is sweeping through the population, sickening your followers and halting progress. Drastic measures may be required.",
|
||||||
|
"meanTimeToHappen": 300,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 500,
|
||||||
|
"maxCorruption": 80
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "We must sacrifice the sick.",
|
||||||
|
"tooltip": "Immediately lose 20% of your Followers, but the plague is stopped.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "Followers",
|
||||||
|
"op": "Multiply",
|
||||||
|
"value": 0.8
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "We will pray for their recovery.",
|
||||||
|
"tooltip": "Lose all passive Follower generation for 120 seconds as the plague runs its course.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ApplyBuff",
|
||||||
|
"buffId": "plague_debuff",
|
||||||
|
"targetStat": "FollowersPerSecond",
|
||||||
|
"multiplier": 0,
|
||||||
|
"duration": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
34
Mods/Events/a_prophets_rise.json
Normal file
34
Mods/Events/a_prophets_rise.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"id": "event_prophets_rise",
|
||||||
|
"title": "A Prophet's Rise",
|
||||||
|
"description": "A charismatic leader has emerged among your followers, inspiring them to new heights of devotion and ingenuity. How shall you guide their efforts?",
|
||||||
|
"meanTimeToHappen": 200,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 800,
|
||||||
|
"maxCorruption": 60
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "Focus their zeal on industry.",
|
||||||
|
"tooltip": "Gain a large, one-time boost to Production.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "AddResource",
|
||||||
|
"targetResource": "Production",
|
||||||
|
"value": 750
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Inspire a population boom.",
|
||||||
|
"tooltip": "Gain a large, one-time boost to Followers.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "AddResource",
|
||||||
|
"targetResource": "Followers",
|
||||||
|
"value": 250
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
38
Mods/Events/divine_inspiration.json
Normal file
38
Mods/Events/divine_inspiration.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"id": "event_divine_inspiration",
|
||||||
|
"title": "Divine Inspiration",
|
||||||
|
"description": "You feel a surge of pure cosmic energy. You can channel this power to inspire your followers in their efforts to either build or cleanse.",
|
||||||
|
"meanTimeToHappen": 250,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 1500,
|
||||||
|
"maxCorruption": 75
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "Inspire frantic construction.",
|
||||||
|
"tooltip": "Greatly increases all passive Production for 2 minutes.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ApplyBuff",
|
||||||
|
"buffId": "inspiration_production_buff",
|
||||||
|
"targetStat": "ProductionPerSecond",
|
||||||
|
"multiplier": 3,
|
||||||
|
"duration": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Inspire planetary healing.",
|
||||||
|
"tooltip": "Greatly reduces all passive Corruption for 2 minutes.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ApplyBuff",
|
||||||
|
"buffId": "inspiration_cleansing_buff",
|
||||||
|
"targetStat": "CorruptionPerSecond",
|
||||||
|
"multiplier": -2,
|
||||||
|
"duration": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
24
Mods/Events/doomsday.json
Normal file
24
Mods/Events/doomsday.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"id": "event_dooms_day",
|
||||||
|
"title": "DOOMS DAY!",
|
||||||
|
"description": "A catastrophic event is unfolding, threatening to annihilate everything in its path",
|
||||||
|
"meanTimeToHappen": 2000,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 500,
|
||||||
|
"maxCorruption": 99
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "NOT TODAY...",
|
||||||
|
"tooltip": "Increase Corruption by 200. (Instant game over)",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "Corruption",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
35
Mods/Events/ecological_collapse.json
Normal file
35
Mods/Events/ecological_collapse.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"id": "event_ecological_collapse",
|
||||||
|
"title": "Ecological Collapse",
|
||||||
|
"description": "The planet's ecosystem has reached a breaking point. Widespread famine and resource scarcity are imminent. We must choose what to prioritize for survival.",
|
||||||
|
"meanTimeToHappen": 400,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 3000,
|
||||||
|
"maxCorruption": 85
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "Ration food for the workers.",
|
||||||
|
"tooltip": "Maintain your production, but lose a significant number of followers to famine.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "AddResource",
|
||||||
|
"targetResource": "Followers",
|
||||||
|
"value": -1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Divert all efforts to food production.",
|
||||||
|
"tooltip": "Save your population, but suffer a permanent blow to your industrial efficiency.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "ProductionPerFollower",
|
||||||
|
"op": "Multiply",
|
||||||
|
"value": 0.75
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
23
Mods/Events/good_harvest.json
Normal file
23
Mods/Events/good_harvest.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"id": "event_good_harvest",
|
||||||
|
"title": "Bountiful Harvest",
|
||||||
|
"description": "A miraculous confluence of weather and soil fertility has led to an unexpectedly large harvest. Our granaries are overflowing!",
|
||||||
|
"meanTimeToHappen": 120,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 100,
|
||||||
|
"maxCorruption": 50
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "A true blessing!",
|
||||||
|
"tooltip": "Gain a large amount (500) of Faith.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "AddResource",
|
||||||
|
"targetResource": "Faith",
|
||||||
|
"value": 500
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
24
Mods/Events/industrial_breakthrough.json
Normal file
24
Mods/Events/industrial_breakthrough.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"id": "event_industrial_breakthrough",
|
||||||
|
"title": "Industrial Breakthrough",
|
||||||
|
"description": "One of your followers has made a revolutionary discovery in manufacturing techniques! This will permanently increase the efficiency of all future industry.",
|
||||||
|
"meanTimeToHappen": 240,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 1000,
|
||||||
|
"maxCorruption": 70
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "A brilliant mind!",
|
||||||
|
"tooltip": "Permanently increases base Production Per Second by 2.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "ProductionPerSecond",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
35
Mods/Events/unstable_rift.json
Normal file
35
Mods/Events/unstable_rift.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"id": "event_unstable_rift",
|
||||||
|
"title": "Unstable Rift",
|
||||||
|
"description": "The planet groans under the weight of your power. A rift of pure corruption has torn open, spewing filth into the environment.",
|
||||||
|
"meanTimeToHappen": 180,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 2000,
|
||||||
|
"maxCorruption": 90
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "Seal it with our power.",
|
||||||
|
"tooltip": "Lose a large amount of Production to seal the rift.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "AddResource",
|
||||||
|
"targetResource": "Production",
|
||||||
|
"value": -1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "This is a necessary evil.",
|
||||||
|
"tooltip": "The rift remains, permanently increasing passive Corruption gain.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "CorruptionPerSecond",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 0.5
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -10,12 +10,12 @@
|
|||||||
"fromResource": "Followers",
|
"fromResource": "Followers",
|
||||||
"fromAmount": 10,
|
"fromAmount": 10,
|
||||||
"toResource": "Faith",
|
"toResource": "Faith",
|
||||||
"toAmount": 250
|
"toAmount": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Corruption",
|
"targetResource": "Corruption",
|
||||||
"value": 5
|
"value": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "Bountiful Harvest",
|
"name": "Bountiful Harvest",
|
||||||
"faithCost": 50,
|
"faithCost": 10,
|
||||||
"followersRequired": 0,
|
"followersRequired": 0,
|
||||||
"unlockedByDefault": true,
|
"unlockedByDefault": true,
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Followers",
|
"targetResource": "Followers",
|
||||||
"value": 10
|
"value": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Corruption",
|
"targetResource": "Corruption",
|
||||||
"value": 0.5
|
"value": 0.2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "Communal Effort",
|
"name": "Communal Effort",
|
||||||
"faithCost": 400,
|
"faithCost": 40,
|
||||||
"followersRequired": 250,
|
"followersRequired": 250,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Production",
|
"targetResource": "Production",
|
||||||
"value": 50
|
"value": 15
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Corruption",
|
"targetResource": "Corruption",
|
||||||
"value": 3
|
"value": 1
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "UnlockMiracle",
|
|
||||||
"miraclesToUnlock": [ "unlock_age_of_industry" ]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
18
Mods/Miracles/craftmenship.json
Normal file
18
Mods/Miracles/craftmenship.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "Craftsmanship",
|
||||||
|
"faithCost": 80,
|
||||||
|
"followersRequired": 300,
|
||||||
|
"productionRequired": 25,
|
||||||
|
"unlockedByDefault": false,
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "ProductionPerFollower",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 0.01
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "DestroySelf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
Mods/Miracles/divine_mandate.json
Normal file
18
Mods/Miracles/divine_mandate.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "Divine Mandate",
|
||||||
|
"faithCost": 300,
|
||||||
|
"followersRequired": 350,
|
||||||
|
"productionRequired": 100,
|
||||||
|
"unlockedByDefault": false,
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "FollowersPerSecond",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 0.1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "DestroySelf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Erect Shrine",
|
"name": "Erect Shrine",
|
||||||
"faithCost": 750,
|
"faithCost": 60,
|
||||||
"followersRequired": 200,
|
"followersRequired": 200,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
@@ -8,12 +8,12 @@
|
|||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "FaithPerFollower",
|
"targetStat": "FaithPerFollower",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": 0.2
|
"value": 0.05
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Corruption",
|
"targetResource": "Corruption",
|
||||||
"value": 5
|
"value": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "Exploit the Earth",
|
"name": "Exploit the Earth",
|
||||||
"faithCost": 500,
|
"faithCost": 200,
|
||||||
"followersRequired": 1200,
|
"followersRequired": 1200,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Production",
|
"targetResource": "Production",
|
||||||
"value": 1000
|
"value": 300
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Corruption",
|
"targetResource": "Corruption",
|
||||||
"value": 20
|
"value": 5
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Fossil Fuel Frenzy",
|
"name": "Fossil Fuel Frenzy",
|
||||||
"faithCost": 5000,
|
"faithCost": 2000,
|
||||||
"followersRequired": 2000,
|
"followersRequired": 2000,
|
||||||
"productionRequired": 500,
|
"productionRequired": 500,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -9,13 +9,13 @@
|
|||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "ProductionPerSecond",
|
"targetStat": "ProductionPerSecond",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": 25
|
"value": 8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "CorruptionPerSecond",
|
"targetStat": "CorruptionPerSecond",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": 2.5
|
"value": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DestroySelf"
|
"type": "DestroySelf"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Geological Survey",
|
"name": "Geological Survey",
|
||||||
"faithCost": 800,
|
"faithCost": 120,
|
||||||
"followersRequired": 500,
|
"followersRequired": 500,
|
||||||
"productionRequired": 0,
|
"productionRequired": 0,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -8,12 +8,12 @@
|
|||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Production",
|
"targetResource": "Production",
|
||||||
"value": 250
|
"value": 80
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Corruption",
|
"targetResource": "Corruption",
|
||||||
"value": 8
|
"value": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "Global Network",
|
"name": "Global Network",
|
||||||
"faithCost": 15000,
|
"faithCost": 4000,
|
||||||
"followersRequired": 5000,
|
"followersRequired": 5000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "UnlockMiracle",
|
"type": "UnlockMiracle",
|
||||||
"miraclesToUnlock": [ "orbital_calculations", "construct_vessel_frame", "launch_ark" ]
|
"miraclesToUnlock": ["orbital_calculations", "construct_vessel_frame"]
|
||||||
},
|
},
|
||||||
{ "type": "DestroySelf" }
|
{ "type": "DestroySelf" }
|
||||||
]
|
]
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Globalization",
|
"name": "Globalization",
|
||||||
"faithCost": 3000,
|
"faithCost": 1200,
|
||||||
"followersRequired": 1500,
|
"followersRequired": 1500,
|
||||||
"productionRequired": 1000,
|
"productionRequired": 1000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -9,13 +9,13 @@
|
|||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "FaithPerFollower",
|
"targetStat": "FaithPerFollower",
|
||||||
"op": "Multiply",
|
"op": "Multiply",
|
||||||
"value": 1.5
|
"value": 1.2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "CorruptionPerSecond",
|
"targetStat": "CorruptionPerSecond",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": 0.2
|
"value": 0.5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DestroySelf"
|
"type": "DestroySelf"
|
||||||
|
@@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "God's Endurance",
|
"name": "God's Endurance",
|
||||||
"faithCost": 500,
|
"faithCost": 100,
|
||||||
"followersRequired": 400,
|
"followersRequired": 400,
|
||||||
"productionRequired": 0,
|
"productionRequired": 0,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "ApplyBuff",
|
"type": "ApplyBuff",
|
||||||
|
"buffId": "gods_endurance",
|
||||||
"targetStat": "FaithPerFollower",
|
"targetStat": "FaithPerFollower",
|
||||||
"multiplier": 2.0,
|
"multiplier": 1.5,
|
||||||
"duration": 60
|
"duration": 30
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "Harness the Sun",
|
"name": "Harness the Sun",
|
||||||
"faithCost": 4000,
|
"faithCost": 1200,
|
||||||
"followersRequired": 2500,
|
"followersRequired": 2500,
|
||||||
"productionRequired": 2000,
|
"productionRequired": 2000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "ApplyBuff",
|
"type": "ApplyBuff",
|
||||||
|
"buffId": "harness_the_sun",
|
||||||
"targetStat": "CorruptionPerSecond",
|
"targetStat": "CorruptionPerSecond",
|
||||||
"multiplier": -1.5,
|
"multiplier": -1.0,
|
||||||
"duration": 120
|
"duration": 60
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Inspire Invention",
|
"name": "Inspire Invention",
|
||||||
"faithCost": 2500,
|
"faithCost": 600,
|
||||||
"followersRequired": 1000,
|
"followersRequired": 1000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
@@ -8,13 +8,13 @@
|
|||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "ProductionPerSecond",
|
"targetStat": "ProductionPerSecond",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": 5
|
"value": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "CorruptionPerSecond",
|
"targetStat": "CorruptionPerSecond",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": 0.5
|
"value": 0.2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Launch Ark",
|
"name": "Launch Ark",
|
||||||
"faithCost": 100000,
|
"faithCost": 25000,
|
||||||
"followersRequired": 5000,
|
"followersRequired": 5000,
|
||||||
"productionRequired": 10000,
|
"productionRequired": 10000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Project: Trajectory",
|
"name": "Project: Trajectory",
|
||||||
"faithCost": 50000,
|
"faithCost": 8000,
|
||||||
"followersRequired": 5000,
|
"followersRequired": 5000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
"effects": [
|
"effects": [
|
||||||
|
18
Mods/Miracles/organized_religion.json
Normal file
18
Mods/Miracles/organized_religion.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "Organized Religion",
|
||||||
|
"faithCost": 800,
|
||||||
|
"followersRequired": 1000,
|
||||||
|
"productionRequired": 500,
|
||||||
|
"unlockedByDefault": false,
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "FaithPerFollower",
|
||||||
|
"op": "Multiply",
|
||||||
|
"value": 1.1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "DestroySelf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
Mods/Miracles/prosperity_boom.json
Normal file
16
Mods/Miracles/prosperity_boom.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "Prosperity Boom",
|
||||||
|
"faithCost": 400,
|
||||||
|
"followersRequired": 1200,
|
||||||
|
"productionRequired": 800,
|
||||||
|
"unlockedByDefault": false,
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "ApplyBuff",
|
||||||
|
"buffId": "prosperity_buff",
|
||||||
|
"targetStat": "FollowersPerSecond",
|
||||||
|
"multiplier": 2.0,
|
||||||
|
"duration": 20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Ritual of Cleansing",
|
"name": "Ritual of Cleansing",
|
||||||
"faithCost": 1000,
|
"faithCost": 200,
|
||||||
"followersRequired": 200,
|
"followersRequired": 200,
|
||||||
"productionRequired": 100,
|
"productionRequired": 100,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
"targetResource": "Corruption",
|
"targetResource": "Corruption",
|
||||||
"value": -10
|
"value": -3
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Sustainable Practices",
|
"name": "Sustainable Practices",
|
||||||
"faithCost": 1200,
|
"faithCost": 200,
|
||||||
"followersRequired": 300,
|
"followersRequired": 300,
|
||||||
"productionRequired": 150,
|
"productionRequired": 150,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "CorruptionPerSecond",
|
"targetStat": "CorruptionPerSecond",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": -0.1
|
"value": -0.2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DestroySelf"
|
"type": "DestroySelf"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Tame the Atom",
|
"name": "Tame the Atom",
|
||||||
"faithCost": 8000,
|
"faithCost": 3000,
|
||||||
"followersRequired": 3000,
|
"followersRequired": 3000,
|
||||||
"productionRequired": 4000,
|
"productionRequired": 4000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
"type": "ModifyStat",
|
"type": "ModifyStat",
|
||||||
"targetStat": "CorruptionPerSecond",
|
"targetStat": "CorruptionPerSecond",
|
||||||
"op": "Add",
|
"op": "Add",
|
||||||
"value": -0.5
|
"value": -0.8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DestroySelf"
|
"type": "DestroySelf"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Age of Industry",
|
"name": "Age of Industry",
|
||||||
"faithCost": 1500,
|
"faithCost": 300,
|
||||||
"followersRequired": 750,
|
"followersRequired": 750,
|
||||||
"productionRequired": 50,
|
"productionRequired": 50,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -14,9 +14,17 @@
|
|||||||
"globalization",
|
"globalization",
|
||||||
"harness_the_sun",
|
"harness_the_sun",
|
||||||
"tame_the_atom",
|
"tame_the_atom",
|
||||||
|
"prosperity_boom",
|
||||||
|
"organized_religion",
|
||||||
"unlock_space_age"
|
"unlock_space_age"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "FollowersPerSecond",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 0.75
|
||||||
|
},
|
||||||
{ "type": "DestroySelf" }
|
{ "type": "DestroySelf" }
|
||||||
],
|
],
|
||||||
"advancesToAge": "The Industrial Age"
|
"advancesToAge": "The Industrial Age"
|
||||||
|
@@ -1,12 +1,28 @@
|
|||||||
{
|
{
|
||||||
"name": "Form Settlement",
|
"name": "Form Settlement",
|
||||||
"faithCost": 300,
|
"faithCost": 30,
|
||||||
"followersRequired": 150,
|
"followersRequired": 150,
|
||||||
"unlockedByDefault": true,
|
"unlockedByDefault": true,
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "UnlockMiracle",
|
"type": "UnlockMiracle",
|
||||||
"miraclesToUnlock": [ "erect_shrine", "communal_effort", "sustainable_practices", "ritual_of_cleansing", "gods_endurance", "geological_survey" ]
|
"miraclesToUnlock": [
|
||||||
|
"erect_shrine",
|
||||||
|
"communal_effort",
|
||||||
|
"sustainable_practices",
|
||||||
|
"ritual_of_cleansing",
|
||||||
|
"gods_endurance",
|
||||||
|
"geological_survey",
|
||||||
|
"divine_mandate",
|
||||||
|
"craftmenship",
|
||||||
|
"unlock_age_of_industry"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "FollowersPerSecond",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 0.5
|
||||||
},
|
},
|
||||||
{ "type": "DestroySelf" }
|
{ "type": "DestroySelf" }
|
||||||
],
|
],
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Age of Space",
|
"name": "Age of Space",
|
||||||
"faithCost": 25000,
|
"faithCost": 6000,
|
||||||
"followersRequired": 4000,
|
"followersRequired": 4000,
|
||||||
"productionRequired": 5000,
|
"productionRequired": 5000,
|
||||||
"unlockedByDefault": false,
|
"unlockedByDefault": false,
|
||||||
@@ -9,6 +9,12 @@
|
|||||||
"type": "UnlockMiracle",
|
"type": "UnlockMiracle",
|
||||||
"miraclesToUnlock": ["global_network", "orbital_calculations"]
|
"miraclesToUnlock": ["global_network", "orbital_calculations"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "ModifyStat",
|
||||||
|
"targetStat": "FollowersPerSecond",
|
||||||
|
"op": "Add",
|
||||||
|
"value": 1.0
|
||||||
|
},
|
||||||
{ "type": "DestroySelf" }
|
{ "type": "DestroySelf" }
|
||||||
],
|
],
|
||||||
"advancesToAge": "The Space Age"
|
"advancesToAge": "The Space Age"
|
||||||
|
@@ -8,26 +8,26 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier2",
|
"tierEnum": "Tier2",
|
||||||
"threshold": 200,
|
"threshold": 30,
|
||||||
"imagePath": "res://Sprites/Follower.png",
|
"imagePath": "res://Sprites/follower_tier_2.png",
|
||||||
"scale": { "x": 0.1, "y": 0.1 }
|
"scale": { "x": 0.1, "y": 0.1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier3",
|
"tierEnum": "Tier3",
|
||||||
"threshold": 500,
|
"threshold": 80,
|
||||||
"imagePath": "res://Sprites/Follower.png",
|
"imagePath": "res://Sprites/follower_tier_3.png",
|
||||||
"scale": { "x": 0.1, "y": 0.1 }
|
"scale": { "x": 0.1, "y": 0.1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier4",
|
"tierEnum": "Tier4",
|
||||||
"threshold": 1000,
|
"threshold": 200,
|
||||||
"imagePath": "res://Sprites/Follower.png",
|
"imagePath": "res://Sprites/follower_tier_4.png",
|
||||||
"scale": { "x": 0.1, "y": 0.1 }
|
"scale": { "x": 0.1, "y": 0.1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier5",
|
"tierEnum": "Tier5",
|
||||||
"threshold": 2500,
|
"threshold": 500,
|
||||||
"imagePath": "res://Sprites/Follower.png",
|
"imagePath": "res://Sprites/follower_tier_5.png",
|
||||||
"scale": { "x": 0.1, "y": 0.1 }
|
"scale": { "x": 0.1, "y": 0.1 }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@@ -2,61 +2,61 @@
|
|||||||
"tiers": [
|
"tiers": [
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier1",
|
"tierEnum": "Tier1",
|
||||||
"threshold": 150,
|
"threshold": 20,
|
||||||
"imagePath": "res://Sprites/Hut.png",
|
"imagePath": "res://Sprites/Hut.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier2",
|
"tierEnum": "Tier2",
|
||||||
"threshold": 750,
|
"threshold": 60,
|
||||||
"imagePath": "res://Sprites/hut_tier_2.png",
|
"imagePath": "res://Sprites/hut_tier_2.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier3",
|
"tierEnum": "Tier3",
|
||||||
"threshold": 1000,
|
"threshold": 120,
|
||||||
"imagePath": "res://Sprites/hut_tier_3.png",
|
"imagePath": "res://Sprites/hut_tier_3.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier4",
|
"tierEnum": "Tier4",
|
||||||
"threshold": 5000,
|
"threshold": 250,
|
||||||
"imagePath": "res://Sprites/castle.png",
|
"imagePath": "res://Sprites/castle.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier5",
|
"tierEnum": "Tier5",
|
||||||
"threshold": 7500,
|
"threshold": 400,
|
||||||
"imagePath": "res://Sprites/house.png",
|
"imagePath": "res://Sprites/house.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier6",
|
"tierEnum": "Tier6",
|
||||||
"threshold": 10000,
|
"threshold": 600,
|
||||||
"imagePath": "res://Sprites/house_tier_2.png",
|
"imagePath": "res://Sprites/house_tier_2.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier7",
|
"tierEnum": "Tier7",
|
||||||
"threshold": 50000,
|
"threshold": 1200,
|
||||||
"imagePath": "res://Sprites/house_tier_3.png",
|
"imagePath": "res://Sprites/house_tier_3.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier8",
|
"tierEnum": "Tier8",
|
||||||
"threshold": 150000,
|
"threshold": 2500,
|
||||||
"imagePath": "res://Sprites/Skyscraper.png",
|
"imagePath": "res://Sprites/Skyscraper.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier9",
|
"tierEnum": "Tier9",
|
||||||
"threshold": 350000,
|
"threshold": 3500,
|
||||||
"imagePath": "res://Sprites/skyscraper_tier_2.png",
|
"imagePath": "res://Sprites/skyscraper_tier_2.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tierEnum": "Tier10",
|
"tierEnum": "Tier10",
|
||||||
"threshold": 550000,
|
"threshold": 5500,
|
||||||
"imagePath": "res://Sprites/skyscraper_tier_3.png",
|
"imagePath": "res://Sprites/skyscraper_tier_3.png",
|
||||||
"scale": { "x": 0.05, "y": 0.05 }
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
}
|
}
|
||||||
|
22
Mods/Tiers/temple_tiers.json
Normal file
22
Mods/Tiers/temple_tiers.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"tiers": [
|
||||||
|
{
|
||||||
|
"tierEnum": "Tier1",
|
||||||
|
"threshold": 200,
|
||||||
|
"imagePath": "res://Sprites/Temple.png",
|
||||||
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tierEnum": "Tier2",
|
||||||
|
"threshold": 600,
|
||||||
|
"imagePath": "res://Sprites/temple_tier_2.png",
|
||||||
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tierEnum": "Tier3",
|
||||||
|
"threshold": 1200,
|
||||||
|
"imagePath": "res://Sprites/temple_tier_3.png",
|
||||||
|
"scale": { "x": 0.05, "y": 0.05 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -1,422 +0,0 @@
|
|||||||
Miracles/blood_ritual.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Blood Ritual",
|
|
||||||
"faithCost": 0,
|
|
||||||
"followersRequired": 25,
|
|
||||||
"productionRequired": 0,
|
|
||||||
"unlockedByDefault": true,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ConvertResource",
|
|
||||||
"fromResource": "Followers",
|
|
||||||
"fromAmount": 10,
|
|
||||||
"toResource": "Faith",
|
|
||||||
"toAmount": 250
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Corruption",
|
|
||||||
"value": 5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/bountiful_harvest.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Bountiful Harvest",
|
|
||||||
"faithCost": 50,
|
|
||||||
"followersRequired": 0,
|
|
||||||
"unlockedByDefault": true,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Followers",
|
|
||||||
"value": 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Corruption",
|
|
||||||
"value": 0.5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/communal_effort.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Communal Effort",
|
|
||||||
"faithCost": 400,
|
|
||||||
"followersRequired": 250,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Production",
|
|
||||||
"value": 50
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Corruption",
|
|
||||||
"value": 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "UnlockMiracle",
|
|
||||||
"miraclesToUnlock": [ "unlock_age_of_industry" ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/construct_vessel_frame.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Project: Ark Frame",
|
|
||||||
"faithCost": 20000,
|
|
||||||
"followersRequired": 5000,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ConvertResource",
|
|
||||||
"fromResource": "Production",
|
|
||||||
"fromAmount": 5000,
|
|
||||||
"toResource": "Faith",
|
|
||||||
"toAmount": 0
|
|
||||||
},
|
|
||||||
{ "type": "DestroySelf" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/erect_shrine.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Erect Shrine",
|
|
||||||
"faithCost": 750,
|
|
||||||
"followersRequired": 200,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "FaithPerFollower",
|
|
||||||
"op": "Add",
|
|
||||||
"value": 0.2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Corruption",
|
|
||||||
"value": 5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/exploit_earth.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Exploit the Earth",
|
|
||||||
"faithCost": 500,
|
|
||||||
"followersRequired": 1200,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Production",
|
|
||||||
"value": 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Corruption",
|
|
||||||
"value": 20
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/fossil_fuel_frenzy.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Fossil Fuel Frenzy",
|
|
||||||
"faithCost": 5000,
|
|
||||||
"followersRequired": 2000,
|
|
||||||
"productionRequired": 500,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "ProductionPerSecond",
|
|
||||||
"op": "Add",
|
|
||||||
"value": 25
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "CorruptionPerSecond",
|
|
||||||
"op": "Add",
|
|
||||||
"value": 2.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "DestroySelf"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/geological_survey.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Geological Survey",
|
|
||||||
"faithCost": 800,
|
|
||||||
"followersRequired": 500,
|
|
||||||
"productionRequired": 0,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Production",
|
|
||||||
"value": 250
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Corruption",
|
|
||||||
"value": 8
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/global_network.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Global Network",
|
|
||||||
"faithCost": 15000,
|
|
||||||
"followersRequired": 5000,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "UnlockMiracle",
|
|
||||||
"miraclesToUnlock": [ "orbital_calculations", "construct_vessel_frame", "launch_ark" ]
|
|
||||||
},
|
|
||||||
{ "type": "DestroySelf" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/globalization.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Globalization",
|
|
||||||
"faithCost": 3000,
|
|
||||||
"followersRequired": 1500,
|
|
||||||
"productionRequired": 1000,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "FaithPerFollower",
|
|
||||||
"op": "Multiply",
|
|
||||||
"value": 1.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "CorruptionPerSecond",
|
|
||||||
"op": "Add",
|
|
||||||
"value": 0.2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "DestroySelf"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/gods_endurance.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "God's Endurance",
|
|
||||||
"faithCost": 500,
|
|
||||||
"followersRequired": 400,
|
|
||||||
"productionRequired": 0,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ApplyBuff",
|
|
||||||
"targetStat": "FaithPerFollower",
|
|
||||||
"multiplier": 2.0,
|
|
||||||
"duration": 60
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/inspire_invention.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Inspire Invention",
|
|
||||||
"faithCost": 2500,
|
|
||||||
"followersRequired": 1000,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "ProductionPerSecond",
|
|
||||||
"op": "Add",
|
|
||||||
"value": 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "CorruptionPerSecond",
|
|
||||||
"op": "Add",
|
|
||||||
"value": 0.5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/launch_ark.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Launch Ark",
|
|
||||||
"faithCost": 100000,
|
|
||||||
"followersRequired": 5000,
|
|
||||||
"productionRequired": 10000,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "Win"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/orbital_calculations.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Project: Trajectory",
|
|
||||||
"faithCost": 50000,
|
|
||||||
"followersRequired": 5000,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "UnlockMiracle",
|
|
||||||
"miraclesToUnlock": [ "launch_ark" ]
|
|
||||||
},
|
|
||||||
{ "type": "DestroySelf" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/ritual_of_cleansing.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Ritual of Cleansing",
|
|
||||||
"faithCost": 1000,
|
|
||||||
"followersRequired": 200,
|
|
||||||
"productionRequired": 100,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "AddResource",
|
|
||||||
"targetResource": "Corruption",
|
|
||||||
"value": -10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/sustainable_practices.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Sustainable Practices",
|
|
||||||
"faithCost": 1200,
|
|
||||||
"followersRequired": 300,
|
|
||||||
"productionRequired": 150,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "ModifyStat",
|
|
||||||
"targetStat": "CorruptionPerSecond",
|
|
||||||
"op": "Add",
|
|
||||||
"value": -0.1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "DestroySelf"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/unlock_age_of_industry.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Age of Industry",
|
|
||||||
"faithCost": 1500,
|
|
||||||
"followersRequired": 750,
|
|
||||||
"productionRequired": 50,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "UnlockMiracle",
|
|
||||||
"miraclesToUnlock": [ "inspire_invention", "exploit_earth", "fossil_fuel_frenzy", "globalization" ]
|
|
||||||
},
|
|
||||||
{ "type": "DestroySelf" }
|
|
||||||
],
|
|
||||||
"advancesToAge": "The Industrial Age"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/unlock_settlement.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Form Settlement",
|
|
||||||
"faithCost": 300,
|
|
||||||
"followersRequired": 150,
|
|
||||||
"unlockedByDefault": true,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "UnlockMiracle",
|
|
||||||
"miraclesToUnlock": [ "erect_shrine", "communal_effort", "sustainable_practices", "ritual_of_cleansing", "gods_endurance", "geological_survey" ]
|
|
||||||
},
|
|
||||||
{ "type": "DestroySelf" }
|
|
||||||
],
|
|
||||||
"advancesToAge": "The Settlement Age"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
Miracles/unlock_space_age.json
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"name": "Age of Space",
|
|
||||||
"faithCost": 10000,
|
|
||||||
"followersRequired": 5000,
|
|
||||||
"unlockedByDefault": false,
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "UnlockMiracle",
|
|
||||||
"miraclesToUnlock": [ "global_network", "orbital_calculations" ]
|
|
||||||
},
|
|
||||||
{ "type": "DestroySelf" }
|
|
||||||
],
|
|
||||||
"advancesToAge": "The Space Age"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
146
README.md
146
README.md
@@ -1,52 +1,65 @@
|
|||||||
# Parasitic God
|
# Parasitic God
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## The Concept
|
## The Concept
|
||||||
|
|
||||||
You are a nascent god, tethered to a small tribe of followers on a vibrant, living world. Their worship is your lifeblood, their growth your only purpose. You grant them miracles, blessing them with bountiful harvests and inspiring great works.
|
You are a nascent god, tethered to a small tribe of followers on a vibrant, living world. Their worship is your lifeblood, their growth your only purpose. You grant them miracles, blessing them with bountiful harvests and inspiring great works.
|
||||||
|
|
||||||
But your power comes at a cost. Every miracle that nurtures your civilization also poisons the planet. The soil turns barren, the forests wither, and the sky darkens. You are their savior and their apocalypse.
|
But your power comes at a cost. Every miracle that nurtures your civilization also poisons the planet. The soil turns barren, the forests wither, and the sky darkens. You are their savior and their apocalypse.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## The Mission
|
## The Mission
|
||||||
|
|
||||||
Guide your people from a simple tribe to a star-faring civilization capable of escaping the dying world. Manage your resources **Faith**, **Followers**, and **Production** while trying to keep the planet's ever-rising **Corruption** at bay.
|
Guide your people from a simple tribe to a star-faring civilization capable of escaping the dying world. Manage your resources **Faith**, **Followers**, and **Production** while trying to keep the planet's ever-rising **Corruption** at bay.
|
||||||
|
|
||||||
Unlock new ages of technology, build a network of cities, and perform the final, desperate miracle to launch your followers into the stars before you consume everything.
|
Unlock new ages of technology, build a network of cities, and perform the final, desperate miracle to launch your followers into the stars before you consume everything.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* **Exponential Growth**
|
|
||||||
|
- **Exponential Growth**
|
||||||
Watch a handful of followers grow into a massive civilization with huts, cities, and procedural road networks.
|
Watch a handful of followers grow into a massive civilization with huts, cities, and procedural road networks.
|
||||||
|
|
||||||
* **A World That Reacts**
|
- **A World That Reacts**
|
||||||
See the direct consequences of your actions as the vibrant globe fades to a corrupted wasteland and forests vanish based on your decisions.
|
See the direct consequences of your actions as the vibrant globe fades to a corrupted wasteland and forests vanish based on your decisions.
|
||||||
|
|
||||||
* **Deeply Moddable**
|
- **Deeply Moddable**
|
||||||
The entire game from miracles and their effects to the visual tiers of your civilization is driven by simple JSON files. If you can edit a text file, you can mod this game.
|
The entire game—from miracles and their effects to the visual tiers of your civilization—is driven by simple JSON files. If you can edit a text file, you can mod this game.
|
||||||
|
|
||||||
* **Strategic Resource Management**
|
- **Strategic Resource Management**
|
||||||
Balance the generation of multiple resources and make difficult choices. Will you sacrifice followers to purge corruption, or push for industrial growth at any cost?
|
Balance the generation of multiple resources and make difficult choices. Will you sacrifice followers to purge corruption, or push for industrial growth at any cost?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Modding Your Universe
|
## Modding Your Universe
|
||||||
|
|
||||||
This game was built from the ground up to be modified. You can add new miracles, change existing ones, and even define new visual tiers for your civilization.
|
This game was built from the ground up to be modified. You can add new miracles, create random events, and even define new visual tiers for your civilization.
|
||||||
|
|
||||||
### Finding the Mods Folder
|
### Finding the Mods Folder
|
||||||
|
|
||||||
First, you need to find the game's `user data` directory. The game will create a `Mods` folder here on its first launch.
|
The game creates a `Mods` folder in its user data directory on first launch:
|
||||||
|
|
||||||
* **Windows:** `%APPDATA%\Godot\app_userdata\ParasiticGod\Mods\`
|
- **Windows:** `%APPDATA%\Godot\app_userdata\ParasiticGod\Mods\`
|
||||||
* **macOS:** `~/Library/Application Support/Godot/app_userdata/ParasiticGod/Mods/`
|
- **macOS:** `~/Library/Application Support/Godot/app_userdata/ParasiticGod/Mods/`
|
||||||
* **Linux:** `~/.local/share/godot/app_userdata/ParasiticGod/Mods/`
|
- **Linux:** `~/.local/share/godot/app_userdata/ParasiticGod/Mods/`
|
||||||
|
|
||||||
Inside, you'll find two folders: `Miracles` and `Tiers`.
|
Inside, you'll find three folders: `Miracles`, `Tiers`, and `Events`.
|
||||||
|
The game also loads a set of base mods from its installation directory (`res://Mods`). Any files you place in the user folder will be added to or override the base game's content.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Creating a New Miracle
|
### Creating a New Miracle
|
||||||
|
|
||||||
To add a new miracle, simply create a new `.json` file in the `Mods/Miracles` folder. The filename will be its unique **ID** (e.g., `my_cool_miracle.json`).
|
To add a new miracle, create a JSON file in `Mods/Miracles`.
|
||||||
|
The filename becomes its unique **ID** (e.g., `my_cool_miracle.json`):
|
||||||
Here is a template with all available fields:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -55,7 +68,7 @@ Here is a template with all available fields:
|
|||||||
"followersRequired": 50,
|
"followersRequired": 50,
|
||||||
"productionRequired": 0,
|
"productionRequired": 0,
|
||||||
"unlockedByDefault": true,
|
"unlockedByDefault": true,
|
||||||
"advancesToAge": "",
|
"advancesToAge": "The Cool Age",
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"type": "AddResource",
|
"type": "AddResource",
|
||||||
@@ -64,28 +77,46 @@ Here is a template with all available fields:
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
````
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Creating a New Event
|
||||||
|
|
||||||
|
To add a new random event, create a JSON file in `Mods/Events`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "event_my_event",
|
||||||
|
"title": "A Thing Happened!",
|
||||||
|
"description": "Something unexpected occurred. What will you do?",
|
||||||
|
"meanTimeToHappen": 120,
|
||||||
|
"trigger": {
|
||||||
|
"minFollowers": 100,
|
||||||
|
"maxCorruption": 50
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "Do the thing!",
|
||||||
|
"tooltip": "Gain 50 Production.",
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "AddResource",
|
||||||
|
"targetResource": "Production",
|
||||||
|
"value": 50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Available Effect Types
|
---
|
||||||
|
|
||||||
This is the core of the modding system. Each miracle can have one or more effects.
|
### Modifying Visual Tiers
|
||||||
|
|
||||||
| Type | Description | Parameters |
|
You can change the visual progression of followers, huts, and temples by editing the files in `Mods/Tiers`.
|
||||||
| :--- | :--- | :--- |
|
The format is a list of tiers, sorted by threshold:
|
||||||
| **`AddResource`** | Adds or subtracts from a core stat. | `targetResource` (Stat), `value` (number) |
|
|
||||||
| **`ConvertResource`** | Trades one resource for another. | `fromResource` (Stat), `fromAmount` (number), `toResource` (Stat), `toAmount` (number) |
|
|
||||||
| **`ModifyStat`** | Permanently changes a passive stat. | `targetStat` (Stat), `op` ("Add" or "Multiply"), `value` (number) |
|
|
||||||
| **`ApplyBuff`** | Applies a temporary multiplier. | `targetStat` (Stat), `multiplier` (number), `duration` (seconds) |
|
|
||||||
| **`UnlockMiracle`** | Unlocks other miracles. | `miraclesToUnlock` (list of miracle IDs) |
|
|
||||||
| **`DestroySelf`** | Removes the miracle's button after use. | (No parameters) |
|
|
||||||
|
|
||||||
**Valid Stat Names:** `Faith`, `Followers`, `Corruption`, `Production`, `ProductionPerSecond`, `CorruptionPerSecond`, `FaithPerFollower`.
|
|
||||||
|
|
||||||
### Modifying Tiers
|
|
||||||
|
|
||||||
You can change the progression of visuals like followers and huts by editing the files in `Mods/Tiers`. For example, to change when followers get new looks, edit `follower_tiers.json`.
|
|
||||||
|
|
||||||
The format is a list of tiers, sorted by their threshold.
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -93,37 +124,54 @@ The format is a list of tiers, sorted by their threshold.
|
|||||||
{
|
{
|
||||||
"tierEnum": "Tier1",
|
"tierEnum": "Tier1",
|
||||||
"threshold": 0,
|
"threshold": 0,
|
||||||
"scenePath": "res://Scenes/Followers/followers_tier_1.tscn"
|
"imagePath": "user://Mods/Tiers/Huts/my_custom_hut.png",
|
||||||
},
|
"scale": { "x": 1.0, "y": 1.0 }
|
||||||
{
|
|
||||||
"tierEnum": "Tier2",
|
|
||||||
"threshold": 200,
|
|
||||||
"scenePath": "res://Scenes/Followers/followers_tier_2.tscn"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
* **`tierEnum`**: Must be one of `Tier1`, `Tier2`, `Tier3`, `Tier4`, `Tier5`.
|
* **tierEnum**: Must be one of `Tier1` through `Tier10`.
|
||||||
* **`threshold`**: The number of followers (or other stat) needed to unlock this visual.
|
* **threshold**: The number of followers needed to unlock this visual.
|
||||||
* **`scenePath`**: The path to the Godot scene (`.tscn`) to display for this tier. You can even point to your own custom scenes if you're an advanced modder\!
|
* **imagePath**: The path to the image file. Use `user://` for mods or `res://` for base assets.
|
||||||
|
* **scale**: Optional X/Y scale multiplier for the image.
|
||||||
|
|
||||||
-----
|
---
|
||||||
|
|
||||||
## 📊 Project Stats
|
### Available Effect Types
|
||||||
📦 **Lines of Code:**
|
|
||||||
|
Both miracles and event options use this list of effects:
|
||||||
|
|
||||||
|
| Type | Description | Parameters |
|
||||||
|
| ------------------- | ----------------------------------- | ---------------------------------------------------------- |
|
||||||
|
| **AddResource** | Adds or subtracts from a core stat. | `targetResource` (Stat), `value` (number) |
|
||||||
|
| **ConvertResource** | Trades one resource for another. | `fromResource`, `fromAmount`, `toResource`, `toAmount` |
|
||||||
|
| **ModifyStat** | Permanently changes a passive stat. | `targetStat`, `op` ("Add" or "Multiply"), `value` |
|
||||||
|
| **ApplyBuff** | Applies a temporary multiplier. | `buffId`, `targetStat`, `multiplier`, `duration` (seconds) |
|
||||||
|
| **UnlockMiracle** | Unlocks other miracles. | `miraclesToUnlock` (list of IDs) |
|
||||||
|
| **DestroySelf** | Removes the miracle's button. | (No parameters) |
|
||||||
|
| **Win** | Triggers the game's win condition. | (No parameters) |
|
||||||
|
|
||||||
|
**Valid Stat Names:**
|
||||||
|
`Faith`, `Followers`, `Corruption`, `Production`, `ProductionPerSecond`, `CorruptionPerSecond`, `FollowersPerSecond`, `FaithPerFollower`, `ProductionPerFollower`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Stats
|
||||||
|
|
||||||
|
**Lines of Code:**
|
||||||

|

|
||||||
|
|
||||||
📈 **Repo Activity:**
|
**Repo Activity:**
|
||||||

|

|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is open source. See the [LICENSE](https://www.google.com/search?q=./LICENSE) file for details.
|
This project is open source. See the [LICENSE](./LICENSE.txt) file for details.
|
||||||
|
|
||||||
-----
|
---
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -131,4 +179,4 @@ While the core code is complete for the jam, you can help by:
|
|||||||
|
|
||||||
* Reporting bugs or balance issues.
|
* Reporting bugs or balance issues.
|
||||||
* Creating cool new miracles and sharing them.
|
* Creating cool new miracles and sharing them.
|
||||||
* Spreading the word\!
|
* Spreading the word!
|
@@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=21 format=3 uid="uid://bfil8sd154327"]
|
[gd_scene load_steps=27 format=3 uid="uid://bfil8sd154327"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://t71ewkpa5uqs" path="res://Scenes/Main/Main.cs" id="1_p8rbg"]
|
[ext_resource type="Script" uid="uid://t71ewkpa5uqs" path="res://Scenes/Main/Main.cs" id="1_p8rbg"]
|
||||||
[ext_resource type="Script" uid="uid://b77vh831r1e3c" path="res://Scenes/Main/MiraclePanel.cs" id="2_hcu3t"]
|
[ext_resource type="Script" uid="uid://b77vh831r1e3c" path="res://Scenes/Main/MiraclePanel.cs" id="2_hcu3t"]
|
||||||
@@ -16,9 +16,17 @@
|
|||||||
[ext_resource type="PackedScene" uid="uid://8w7tvsgkev1y" path="res://Scenes/tree.tscn" id="8_hcu3t"]
|
[ext_resource type="PackedScene" uid="uid://8w7tvsgkev1y" path="res://Scenes/tree.tscn" id="8_hcu3t"]
|
||||||
[ext_resource type="Shader" uid="uid://bf8nk145fjkgh" path="res://Shaders/corruption_shader.gdshader" id="9_wgovn"]
|
[ext_resource type="Shader" uid="uid://bf8nk145fjkgh" path="res://Shaders/corruption_shader.gdshader" id="9_wgovn"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cqkye7yykakns" path="res://Scenes/Followers/FollowerMarker.tscn" id="11_5ci8a"]
|
[ext_resource type="PackedScene" uid="uid://cqkye7yykakns" path="res://Scenes/Followers/FollowerMarker.tscn" id="11_5ci8a"]
|
||||||
|
[ext_resource type="Script" uid="uid://djmtle2h3yd2e" path="res://Scripts/Components/PauseManager.cs" id="11_xggvw"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://wysxqe44rxhf" path="res://Scenes/TempleMarker.tscn" id="14_udh0u"]
|
||||||
[ext_resource type="PackedScene" uid="uid://xk2xirjd1sma" path="res://Scenes/moddable_visual.tscn" id="17_qdkat"]
|
[ext_resource type="PackedScene" uid="uid://xk2xirjd1sma" path="res://Scenes/moddable_visual.tscn" id="17_qdkat"]
|
||||||
[ext_resource type="Script" uid="uid://furbvcmw31bx" path="res://Scripts/Components/ForestVisualizer.cs" id="18_qdkat"]
|
[ext_resource type="Script" uid="uid://furbvcmw31bx" path="res://Scripts/Components/ForestVisualizer.cs" id="18_qdkat"]
|
||||||
[ext_resource type="Script" uid="uid://cw8gpeaq3yfjn" path="res://Scripts/Components/RoadManager.cs" id="19_qdkat"]
|
[ext_resource type="Script" uid="uid://cw8gpeaq3yfjn" path="res://Scripts/Components/RoadManager.cs" id="19_qdkat"]
|
||||||
|
[ext_resource type="Script" uid="uid://2ipbgwlx1ld1" path="res://Scripts/Components/EventManager.cs" id="22_iwp64"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://gdejd44km3co" path="res://Scenes/UI/event_popup.tscn" id="23_4etfk"]
|
||||||
|
[ext_resource type="Script" uid="uid://dvmrpbba7plsf" path="res://Scripts/EnableMainThemeMusic.cs" id="24_4etfk"]
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xggvw"]
|
||||||
|
bg_color = Color(0, 0, 0, 0.733333)
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_cv8e0"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_cv8e0"]
|
||||||
shader = ExtResource("9_wgovn")
|
shader = ExtResource("9_wgovn")
|
||||||
@@ -36,7 +44,10 @@ _productionLabel = NodePath("UiLayer/Control/Main/Top/ProductionLabel")
|
|||||||
_miraclePanel = NodePath("UiLayer/Control/Main/ScrollContainer/Bottom")
|
_miraclePanel = NodePath("UiLayer/Control/Main/ScrollContainer/Bottom")
|
||||||
_worldSprite = NodePath("World Sprite")
|
_worldSprite = NodePath("World Sprite")
|
||||||
|
|
||||||
[node name="UiLayer" type="CanvasLayer" parent="."]
|
[node name="UiLayer" type="CanvasLayer" parent="." node_paths=PackedStringArray("_pauseButton", "_pauseMenu")]
|
||||||
|
script = ExtResource("11_xggvw")
|
||||||
|
_pauseButton = NodePath("MarginContainer/Button")
|
||||||
|
_pauseMenu = NodePath("PanelContainer")
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="UiLayer"]
|
[node name="Control" type="Control" parent="UiLayer"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
@@ -47,6 +58,7 @@ grow_horizontal = 2
|
|||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="Main" type="MarginContainer" parent="UiLayer/Control"]
|
[node name="Main" type="MarginContainer" parent="UiLayer/Control"]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
@@ -57,6 +69,7 @@ grow_horizontal = 2
|
|||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
size_flags_horizontal = 4
|
size_flags_horizontal = 4
|
||||||
size_flags_vertical = 0
|
size_flags_vertical = 0
|
||||||
|
mouse_filter = 2
|
||||||
theme_override_constants/margin_left = 8
|
theme_override_constants/margin_left = 8
|
||||||
theme_override_constants/margin_top = 8
|
theme_override_constants/margin_top = 8
|
||||||
theme_override_constants/margin_right = 8
|
theme_override_constants/margin_right = 8
|
||||||
@@ -66,6 +79,7 @@ theme_override_constants/margin_bottom = 8
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 4
|
size_flags_horizontal = 4
|
||||||
size_flags_vertical = 0
|
size_flags_vertical = 0
|
||||||
|
mouse_filter = 2
|
||||||
alignment = 1
|
alignment = 1
|
||||||
|
|
||||||
[node name="FaithLabel" type="Label" parent="UiLayer/Control/Main/Top"]
|
[node name="FaithLabel" type="Label" parent="UiLayer/Control/Main/Top"]
|
||||||
@@ -123,6 +137,44 @@ stream = ExtResource("6_32vk6")
|
|||||||
[node name="BuffAdded" type="AudioStreamPlayer" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
|
[node name="BuffAdded" type="AudioStreamPlayer" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
|
||||||
stream = ExtResource("7_crdpj")
|
stream = ExtResource("7_crdpj")
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="UiLayer"]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
theme_override_constants/margin_left = 4
|
||||||
|
theme_override_constants/margin_top = 4
|
||||||
|
theme_override_constants/margin_right = 4
|
||||||
|
theme_override_constants/margin_bottom = 4
|
||||||
|
|
||||||
|
[node name="Button" type="Button" parent="UiLayer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
size_flags_vertical = 0
|
||||||
|
focus_mode = 0
|
||||||
|
text = "Pause"
|
||||||
|
|
||||||
|
[node name="PanelContainer" type="PanelContainer" parent="UiLayer"]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
mouse_filter = 2
|
||||||
|
theme_override_styles/panel = SubResource("StyleBoxFlat_xggvw")
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="UiLayer/PanelContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 1
|
||||||
|
text = "Paused"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
uppercase = true
|
||||||
|
|
||||||
[node name="Notification Layer" type="CanvasLayer" parent="." node_paths=PackedStringArray("_sfx")]
|
[node name="Notification Layer" type="CanvasLayer" parent="." node_paths=PackedStringArray("_sfx")]
|
||||||
layer = 3
|
layer = 3
|
||||||
script = ExtResource("6_iwp64")
|
script = ExtResource("6_iwp64")
|
||||||
@@ -132,6 +184,14 @@ _sfx = NodePath("Advance Age")
|
|||||||
[node name="Advance Age" type="AudioStreamPlayer" parent="Notification Layer"]
|
[node name="Advance Age" type="AudioStreamPlayer" parent="Notification Layer"]
|
||||||
stream = ExtResource("8_4etfk")
|
stream = ExtResource("8_4etfk")
|
||||||
|
|
||||||
|
[node name="CenterContainer" type="CenterContainer" parent="Notification Layer"]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="Camera2D" type="Camera2D" parent="."]
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
|
||||||
[node name="World Sprite" type="Sprite2D" parent="."]
|
[node name="World Sprite" type="Sprite2D" parent="."]
|
||||||
@@ -141,7 +201,14 @@ scale = Vector2(2.41247, 2.41247)
|
|||||||
texture = ExtResource("4_i3fi7")
|
texture = ExtResource("4_i3fi7")
|
||||||
metadata/_edit_lock_ = true
|
metadata/_edit_lock_ = true
|
||||||
|
|
||||||
|
[node name="RoadManager" type="Node2D" parent="." node_paths=PackedStringArray("_markersContainer")]
|
||||||
|
script = ExtResource("19_qdkat")
|
||||||
|
_markersContainer = NodePath("../Hut Markers")
|
||||||
|
metadata/_custom_type_script = "uid://cw8gpeaq3yfjn"
|
||||||
|
metadata/_edit_lock_ = true
|
||||||
|
|
||||||
[node name="Hut Markers" type="Node2D" parent="."]
|
[node name="Hut Markers" type="Node2D" parent="."]
|
||||||
|
metadata/_edit_lock_ = true
|
||||||
|
|
||||||
[node name="HutMarker" parent="Hut Markers" instance=ExtResource("6_cv8e0")]
|
[node name="HutMarker" parent="Hut Markers" instance=ExtResource("6_cv8e0")]
|
||||||
position = Vector2(-1, -29)
|
position = Vector2(-1, -29)
|
||||||
@@ -206,7 +273,52 @@ position = Vector2(65, 472)
|
|||||||
[node name="HutMarker21" parent="Hut Markers" instance=ExtResource("6_cv8e0")]
|
[node name="HutMarker21" parent="Hut Markers" instance=ExtResource("6_cv8e0")]
|
||||||
position = Vector2(-209, 28)
|
position = Vector2(-209, 28)
|
||||||
|
|
||||||
|
[node name="TemplesContainer" type="Node2D" parent="."]
|
||||||
|
|
||||||
|
[node name="HutMarker" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
|
||||||
|
[node name="HutMarker2" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(78, -66)
|
||||||
|
|
||||||
|
[node name="HutMarker3" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(337, -80)
|
||||||
|
|
||||||
|
[node name="HutMarker4" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(357, 67)
|
||||||
|
|
||||||
|
[node name="HutMarker5" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(545, 76)
|
||||||
|
|
||||||
|
[node name="HutMarker6" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(595, -67)
|
||||||
|
|
||||||
|
[node name="HutMarker7" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(572, -243)
|
||||||
|
|
||||||
|
[node name="HutMarker8" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(214, -237)
|
||||||
|
|
||||||
|
[node name="HutMarker9" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(-112, -46)
|
||||||
|
|
||||||
|
[node name="HutMarker11" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(-140, 206)
|
||||||
|
|
||||||
|
[node name="HutMarker12" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(234, 161)
|
||||||
|
|
||||||
|
[node name="HutMarker13" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(187, 425)
|
||||||
|
|
||||||
|
[node name="HutMarker14" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(-48, 338)
|
||||||
|
rotation = -0.0412825
|
||||||
|
|
||||||
|
[node name="HutMarker10" parent="TemplesContainer" instance=ExtResource("14_udh0u")]
|
||||||
|
position = Vector2(-242, 10)
|
||||||
|
|
||||||
[node name="Followers Markers" type="Node2D" parent="."]
|
[node name="Followers Markers" type="Node2D" parent="."]
|
||||||
|
metadata/_edit_lock_ = true
|
||||||
|
|
||||||
[node name="FollowerMarker" parent="Followers Markers" instance=ExtResource("11_5ci8a")]
|
[node name="FollowerMarker" parent="Followers Markers" instance=ExtResource("11_5ci8a")]
|
||||||
|
|
||||||
@@ -265,6 +377,7 @@ position = Vector2(-88, -32)
|
|||||||
position = Vector2(82, -234)
|
position = Vector2(82, -234)
|
||||||
|
|
||||||
[node name="ForestContainer" type="Node2D" parent="."]
|
[node name="ForestContainer" type="Node2D" parent="."]
|
||||||
|
metadata/_edit_lock_ = true
|
||||||
|
|
||||||
[node name="Tree" parent="ForestContainer" instance=ExtResource("8_hcu3t")]
|
[node name="Tree" parent="ForestContainer" instance=ExtResource("8_hcu3t")]
|
||||||
position = Vector2(214, 38)
|
position = Vector2(214, 38)
|
||||||
@@ -5566,7 +5679,19 @@ script = ExtResource("18_qdkat")
|
|||||||
_treesContainer = NodePath("../ForestContainer")
|
_treesContainer = NodePath("../ForestContainer")
|
||||||
metadata/_custom_type_script = "uid://furbvcmw31bx"
|
metadata/_custom_type_script = "uid://furbvcmw31bx"
|
||||||
|
|
||||||
[node name="RoadManager" type="Node2D" parent="." node_paths=PackedStringArray("_markersContainer")]
|
[node name="TemplesVisualizer" type="Node" parent="." node_paths=PackedStringArray("_markersContainer")]
|
||||||
script = ExtResource("19_qdkat")
|
script = ExtResource("8_cv8e0")
|
||||||
_markersContainer = NodePath("../Hut Markers")
|
_markersContainer = NodePath("../TemplesContainer")
|
||||||
metadata/_custom_type_script = "uid://cw8gpeaq3yfjn"
|
_unitsPerMarker = 1
|
||||||
|
Category = 2
|
||||||
|
_moddableVisualScene = ExtResource("17_qdkat")
|
||||||
|
metadata/_custom_type_script = "uid://dj2wyrq07gfp2"
|
||||||
|
|
||||||
|
[node name="EventManager" type="Node" parent="." node_paths=PackedStringArray("_eventPopupContainer")]
|
||||||
|
script = ExtResource("22_iwp64")
|
||||||
|
_eventPopupScene = ExtResource("23_4etfk")
|
||||||
|
_eventPopupContainer = NodePath("../Notification Layer/CenterContainer")
|
||||||
|
metadata/_custom_type_script = "uid://2ipbgwlx1ld1"
|
||||||
|
|
||||||
|
[node name="Node" type="Node" parent="."]
|
||||||
|
script = ExtResource("24_4etfk")
|
||||||
|
@@ -86,6 +86,11 @@ public partial class MiracleButton : Button
|
|||||||
missingRequirements.Add("Already unlocked subsequent powers.");
|
missingRequirements.Add("Already unlocked subsequent powers.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsBuffAlreadyActive(state))
|
||||||
|
{
|
||||||
|
missingRequirements.Add("This buff is already active.");
|
||||||
|
}
|
||||||
|
|
||||||
if (missingRequirements.Any())
|
if (missingRequirements.Any())
|
||||||
{
|
{
|
||||||
Disabled = true;
|
Disabled = true;
|
||||||
@@ -145,4 +150,16 @@ public partial class MiracleButton : Button
|
|||||||
|
|
||||||
return unlockEffect.MiraclesToUnlock.All(state.IsMiracleUnlocked);
|
return unlockEffect.MiraclesToUnlock.All(state.IsMiracleUnlocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsBuffAlreadyActive(GameState state)
|
||||||
|
{
|
||||||
|
var buffEffect = _miracle.Effects.OfType<ApplyBuffEffect>().FirstOrDefault();
|
||||||
|
|
||||||
|
if (buffEffect == null || string.IsNullOrEmpty(buffEffect.BuffId))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.IsBuffActive(buffEffect.BuffId);
|
||||||
|
}
|
||||||
}
|
}
|
14
Scenes/TempleMarker.tscn
Normal file
14
Scenes/TempleMarker.tscn
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://wysxqe44rxhf"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://djaf0gv8s7qib" path="res://Scripts/FollowerMarker.cs" id="1_x8f1l"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dcs48aa84w21u" path="res://icon.svg" id="2_tc18m"]
|
||||||
|
|
||||||
|
[node name="HutMarker" type="Marker2D"]
|
||||||
|
script = ExtResource("1_x8f1l")
|
||||||
|
metadata/_custom_type_script = "uid://djaf0gv8s7qib"
|
||||||
|
|
||||||
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
|
visible = false
|
||||||
|
modulate = Color(0.406241, 0.161792, 0.609211, 1)
|
||||||
|
scale = Vector2(0.235, 0.235)
|
||||||
|
texture = ExtResource("2_tc18m")
|
8
Scenes/UI/event_option_button.tscn
Normal file
8
Scenes/UI/event_option_button.tscn
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[gd_scene format=3 uid="uid://b2o5rufqn8dpf"]
|
||||||
|
|
||||||
|
[node name="EventOptionButton" type="Button"]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
37
Scenes/UI/event_popup.tscn
Normal file
37
Scenes/UI/event_popup.tscn
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://gdejd44km3co"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://h1x5eqt0lc5m" path="res://Scripts/UI/EventPopup.cs" id="1_lkb7n"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b2o5rufqn8dpf" path="res://Scenes/UI/event_option_button.tscn" id="2_gk0qx"]
|
||||||
|
|
||||||
|
[node name="EventPopup" type="PanelContainer" node_paths=PackedStringArray("_titleLabel", "_descriptionLabel", "_optionsContainer")]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_lkb7n")
|
||||||
|
_titleLabel = NodePath("VBoxContainer/Title")
|
||||||
|
_descriptionLabel = NodePath("VBoxContainer/Description")
|
||||||
|
_optionsContainer = NodePath("VBoxContainer/OptionButtons")
|
||||||
|
_optionButtonScene = ExtResource("2_gk0qx")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="Title" type="Label" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 6
|
||||||
|
text = "TITLE"
|
||||||
|
|
||||||
|
[node name="Description" type="RichTextLabel" parent="VBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(320, 128)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
fit_content = true
|
||||||
|
|
||||||
|
[node name="OptionButtons" type="VBoxContainer" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
@@ -1,7 +1,9 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://kcla4knp80mq"]
|
[gd_scene load_steps=6 format=3 uid="uid://kcla4knp80mq"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cbdokimy0qarg" path="res://Scripts/MainMenu.cs" id="1_8fo1c"]
|
[ext_resource type="Script" uid="uid://cbdokimy0qarg" path="res://Scripts/MainMenu.cs" id="1_8fo1c"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cmhvni5njpmee" path="res://Scenes/main_menu.tscn" id="2_ek8ke"]
|
[ext_resource type="PackedScene" uid="uid://cmhvni5njpmee" path="res://Scenes/main_menu.tscn" id="2_ek8ke"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://defdxbv24q6l1" path="res://Sfx/The Hollow Throne.mp3" id="3_ek8ke"]
|
||||||
|
[ext_resource type="Script" uid="uid://bif3eyfa1lgl4" path="res://Scripts/DisableMainThemeMusic.cs" id="4_eoghk"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i2yjh"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i2yjh"]
|
||||||
bg_color = Color(0, 0, 0, 1)
|
bg_color = Color(0, 0, 0, 1)
|
||||||
@@ -44,3 +46,12 @@ vertical_alignment = 1
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Quit"
|
text = "Quit"
|
||||||
flat = true
|
flat = true
|
||||||
|
|
||||||
|
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
||||||
|
stream = ExtResource("3_ek8ke")
|
||||||
|
volume_db = -3.0
|
||||||
|
autoplay = true
|
||||||
|
parameters/looping = true
|
||||||
|
|
||||||
|
[node name="Node" type="Node" parent="."]
|
||||||
|
script = ExtResource("4_eoghk")
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
[gd_scene load_steps=6 format=3 uid="uid://cmhvni5njpmee"]
|
[gd_scene load_steps=7 format=3 uid="uid://cmhvni5njpmee"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cbdokimy0qarg" path="res://Scripts/MainMenu.cs" id="1_1ehe0"]
|
[ext_resource type="Script" uid="uid://cbdokimy0qarg" path="res://Scripts/MainMenu.cs" id="1_1ehe0"]
|
||||||
[ext_resource type="FontFile" uid="uid://wofoiaejxgsp" path="res://Fonts/Playful Boxes.otf" id="1_28flt"]
|
[ext_resource type="FontFile" uid="uid://wofoiaejxgsp" path="res://Fonts/Playful Boxes.otf" id="1_28flt"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d2wi2cs20q2b6" path="res://Parasitic_God.png" id="1_48xlc"]
|
[ext_resource type="Texture2D" uid="uid://d2wi2cs20q2b6" path="res://Parasitic_God.png" id="1_48xlc"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bfil8sd154327" path="res://Scenes/Main/Main.tscn" id="2_ce3w2"]
|
[ext_resource type="PackedScene" uid="uid://kvpk5wrcp3rv" path="res://Scenes/tutorial_scene.tscn" id="2_ce3w2"]
|
||||||
|
[ext_resource type="Script" uid="uid://dvmrpbba7plsf" path="res://Scripts/EnableMainThemeMusic.cs" id="5_n45e2"]
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_48xlc"]
|
[sub_resource type="LabelSettings" id="LabelSettings_48xlc"]
|
||||||
font = ExtResource("1_28flt")
|
font = ExtResource("1_28flt")
|
||||||
@@ -65,3 +66,6 @@ text = "Play"
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_font_sizes/font_size = 30
|
theme_override_font_sizes/font_size = 30
|
||||||
text = "Exit"
|
text = "Exit"
|
||||||
|
|
||||||
|
[node name="Node" type="Node" parent="."]
|
||||||
|
script = ExtResource("5_n45e2")
|
||||||
|
10
Scenes/main_theme_music.tscn
Normal file
10
Scenes/main_theme_music.tscn
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://b7we8gtene47t"]
|
||||||
|
|
||||||
|
[ext_resource type="AudioStream" uid="uid://wm3vocs0kkk8" path="res://Sfx/MainTheme.mp3" id="1_f0c52"]
|
||||||
|
|
||||||
|
[node name="MainThemeMusic" type="AudioStreamPlayer"]
|
||||||
|
process_mode = 3
|
||||||
|
stream = ExtResource("1_f0c52")
|
||||||
|
volume_db = -5.0
|
||||||
|
autoplay = true
|
||||||
|
parameters/looping = true
|
26
Scenes/tutorial_scene.tscn
Normal file
26
Scenes/tutorial_scene.tscn
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
[gd_scene load_steps=5 format=3 uid="uid://kvpk5wrcp3rv"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://d08d3pi7sx8k3" path="res://Scripts/UI/TutorialScene.cs" id="1_epmsy"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bfil8sd154327" path="res://Scenes/Main/Main.tscn" id="2_mw53g"]
|
||||||
|
[ext_resource type="Resource" uid="uid://dxgpvgx7axp88" path="res://Dialogue/tutorial.dialogue" id="3_oaf0i"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dg6ac3jb1366r" path="res://Sprites/globe.svg" id="4_7u0dx"]
|
||||||
|
|
||||||
|
[node name="TutorialScene" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_epmsy")
|
||||||
|
_mainGameScene = ExtResource("2_mw53g")
|
||||||
|
_tutorialDialogue = ExtResource("3_oaf0i")
|
||||||
|
|
||||||
|
[node name="World" type="TextureRect" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = 195.0
|
||||||
|
offset_top = -98.0
|
||||||
|
offset_right = 915.0
|
||||||
|
offset_bottom = 732.0
|
||||||
|
texture = ExtResource("4_7u0dx")
|
||||||
|
expand_mode = 4
|
@@ -1,7 +1,9 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://dtuyx1f5fa8sy"]
|
[gd_scene load_steps=6 format=3 uid="uid://dtuyx1f5fa8sy"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cbdokimy0qarg" path="res://Scripts/MainMenu.cs" id="1_a00f1"]
|
[ext_resource type="Script" uid="uid://cbdokimy0qarg" path="res://Scripts/MainMenu.cs" id="1_a00f1"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cmhvni5njpmee" path="res://Scenes/main_menu.tscn" id="2_awi1s"]
|
[ext_resource type="PackedScene" uid="uid://cmhvni5njpmee" path="res://Scenes/main_menu.tscn" id="2_awi1s"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://46kqkf4ckqek" path="res://Sfx/Ascend Beyond.mp3" id="3_awi1s"]
|
||||||
|
[ext_resource type="Script" uid="uid://bif3eyfa1lgl4" path="res://Scripts/DisableMainThemeMusic.cs" id="4_bwc64"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i2yjh"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i2yjh"]
|
||||||
bg_color = Color(0, 0, 0, 1)
|
bg_color = Color(0, 0, 0, 1)
|
||||||
@@ -43,3 +45,12 @@ vertical_alignment = 1
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Quit"
|
text = "Quit"
|
||||||
flat = true
|
flat = true
|
||||||
|
|
||||||
|
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
||||||
|
stream = ExtResource("3_awi1s")
|
||||||
|
volume_db = -3.0
|
||||||
|
autoplay = true
|
||||||
|
parameters/looping = true
|
||||||
|
|
||||||
|
[node name="Node" type="Node" parent="."]
|
||||||
|
script = ExtResource("4_bwc64")
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
using ParasiticGod.Scripts;
|
|
||||||
using ParasiticGod.Scripts.Core.Effects;
|
using ParasiticGod.Scripts.Core.Effects;
|
||||||
using ParasiticGod.Scripts.Singletons;
|
using ParasiticGod.Scripts.Singletons;
|
||||||
|
|
||||||
@@ -34,16 +33,16 @@ public partial class ActiveBuffsManager : Node
|
|||||||
var buffInstance = _activeBuffScene.Instantiate<ActiveBuffUi>();
|
var buffInstance = _activeBuffScene.Instantiate<ActiveBuffUi>();
|
||||||
AddChild(buffInstance);
|
AddChild(buffInstance);
|
||||||
buffInstance.SetBuff(buff);
|
buffInstance.SetBuff(buff);
|
||||||
_activeBuffUis.Add(buff.Id, buffInstance);
|
_activeBuffUis.Add(buff.InstanceId, buffInstance);
|
||||||
_buffAddedSfx?.Play();
|
_buffAddedSfx?.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBuffRemoved(Buff buff)
|
private void OnBuffRemoved(Buff buff)
|
||||||
{
|
{
|
||||||
if (_activeBuffUis.TryGetValue(buff.Id, out var buffUi))
|
if (_activeBuffUis.TryGetValue(buff.InstanceId, out var buffUi))
|
||||||
{
|
{
|
||||||
buffUi.QueueFree();
|
buffUi.QueueFree();
|
||||||
_activeBuffUis.Remove(buff.Id);
|
_activeBuffUis.Remove(buff.InstanceId);
|
||||||
_buffRemovedSfx?.Play();
|
_buffRemovedSfx?.Play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
73
Scripts/Components/EventManager.cs
Normal file
73
Scripts/Components/EventManager.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
using Limbo.Console.Sharp;
|
||||||
|
using ParasiticGod.Scripts.Core;
|
||||||
|
using ParasiticGod.Scripts.Singletons;
|
||||||
|
using ParasiticGod.Scripts.UI;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts.Components;
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class EventManager : Node
|
||||||
|
{
|
||||||
|
[Export] private double _checkInterval = 5.0;
|
||||||
|
[Export] private PackedScene _eventPopupScene;
|
||||||
|
[Export] private Container _eventPopupContainer;
|
||||||
|
|
||||||
|
private List<EventDefinition> _allEvents;
|
||||||
|
private Timer _timer;
|
||||||
|
private RandomNumberGenerator _rng = new();
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
RegisterConsoleCommands();
|
||||||
|
_allEvents = GameBus.Instance.AllEvents;
|
||||||
|
|
||||||
|
_timer = new Timer { WaitTime = _checkInterval, Autostart = true };
|
||||||
|
AddChild(_timer);
|
||||||
|
_timer.Timeout += OnCheckEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCheckEvents()
|
||||||
|
{
|
||||||
|
if (GetTree().Paused) return;
|
||||||
|
|
||||||
|
var state = GameBus.Instance.CurrentState;
|
||||||
|
|
||||||
|
foreach (var ev in _allEvents)
|
||||||
|
{
|
||||||
|
if (state.Get(Stat.Followers) < ev.Trigger.MinFollowers) continue;
|
||||||
|
if (state.Get(Stat.Corruption) > ev.Trigger.MaxCorruption) continue;
|
||||||
|
|
||||||
|
var probability = _checkInterval / ev.MeanTimeToHappen;
|
||||||
|
if (_rng.Randf() < probability)
|
||||||
|
{
|
||||||
|
FireEvent(ev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FireEvent(EventDefinition eventDef)
|
||||||
|
{
|
||||||
|
GameBus.Instance.SetPause(true);
|
||||||
|
|
||||||
|
var popup = _eventPopupScene.Instantiate<EventPopup>();
|
||||||
|
_eventPopupContainer.AddChild(popup);
|
||||||
|
popup.DisplayEvent(eventDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConsoleCommand("trigger_event", "Triggers an event by its ID for testing purposes.")]
|
||||||
|
private void TriggerEventCommand(string eventId)
|
||||||
|
{
|
||||||
|
var eventDef = _allEvents.Find(e => e.Id == eventId);
|
||||||
|
if (eventDef != null)
|
||||||
|
{
|
||||||
|
FireEvent(eventDef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GD.PushError($"No event found with ID: {eventId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
Scripts/Components/EventManager.cs.uid
Normal file
1
Scripts/Components/EventManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://2ipbgwlx1ld1
|
43
Scripts/Components/PauseManager.cs
Normal file
43
Scripts/Components/PauseManager.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using Godot;
|
||||||
|
using ParasiticGod.Scripts.Singletons;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts.Components;
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class PauseManager : CanvasLayer
|
||||||
|
{
|
||||||
|
[Export] private Button _pauseButton;
|
||||||
|
[Export] private Control _pauseMenu;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
ProcessMode = ProcessModeEnum.Always;
|
||||||
|
_pauseMenu.Hide();
|
||||||
|
_pauseButton.Pressed += TogglePause;
|
||||||
|
|
||||||
|
GameBus.Instance.PauseStateChanged += OnPauseStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Input(InputEvent @event)
|
||||||
|
{
|
||||||
|
if (@event.IsActionPressed("pause")) TogglePause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
if (GameBus.Instance != null)
|
||||||
|
{
|
||||||
|
GameBus.Instance.PauseStateChanged -= OnPauseStateChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TogglePause()
|
||||||
|
{
|
||||||
|
GameBus.Instance.SetPause(!GetTree().Paused);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPauseStateChanged(bool isPaused)
|
||||||
|
{
|
||||||
|
_pauseMenu.Visible = isPaused;
|
||||||
|
}
|
||||||
|
}
|
1
Scripts/Components/PauseManager.cs.uid
Normal file
1
Scripts/Components/PauseManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://djmtle2h3yd2e
|
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Godot.Collections;
|
|
||||||
using ParasiticGod.Scripts.Core;
|
using ParasiticGod.Scripts.Core;
|
||||||
using ParasiticGod.Scripts.Singletons;
|
using ParasiticGod.Scripts.Singletons;
|
||||||
|
|
||||||
@@ -9,7 +8,7 @@ namespace ParasiticGod.Scripts.Components;
|
|||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class PopulationVisualizer : Node
|
public partial class PopulationVisualizer : Node
|
||||||
{
|
{
|
||||||
public enum VisualCategory { Followers, Huts }
|
public enum VisualCategory { Followers, Huts, Temples }
|
||||||
|
|
||||||
[Export] private Node2D _markersContainer;
|
[Export] private Node2D _markersContainer;
|
||||||
[Export] private int _unitsPerMarker = 5;
|
[Export] private int _unitsPerMarker = 5;
|
||||||
@@ -32,6 +31,9 @@ public partial class PopulationVisualizer : Node
|
|||||||
case VisualCategory.Huts:
|
case VisualCategory.Huts:
|
||||||
_tiers = GameBus.Instance.HutTiers;
|
_tiers = GameBus.Instance.HutTiers;
|
||||||
break;
|
break;
|
||||||
|
case VisualCategory.Temples:
|
||||||
|
_tiers = GameBus.Instance.TempleTiers;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
GD.PushError($"PopulationVisualizer has an invalid category: {Category}");
|
GD.PushError($"PopulationVisualizer has an invalid category: {Category}");
|
||||||
return;
|
return;
|
||||||
@@ -61,6 +63,7 @@ public partial class PopulationVisualizer : Node
|
|||||||
{
|
{
|
||||||
VisualCategory.Followers => (long)newState.Get(Stat.Followers),
|
VisualCategory.Followers => (long)newState.Get(Stat.Followers),
|
||||||
VisualCategory.Huts => (long)newState.Get(Stat.Followers),
|
VisualCategory.Huts => (long)newState.Get(Stat.Followers),
|
||||||
|
VisualCategory.Temples => (long)newState.Get(Stat.Followers),
|
||||||
_ => 0
|
_ => 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -6,20 +6,30 @@ namespace ParasiticGod.Scripts.Core.Effects;
|
|||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class ApplyBuffEffect : Effect
|
public partial class ApplyBuffEffect : Effect
|
||||||
{
|
{
|
||||||
|
[Export] public string BuffId { get; set; }
|
||||||
[Export] public Stat TargetStat { get; set; }
|
[Export] public Stat TargetStat { get; set; }
|
||||||
[Export] public float Multiplier { get; set; } = 2.0f;
|
[Export] public float Multiplier { get; set; } = 2.0f;
|
||||||
[Export] public double Duration { get; set; } = 30.0;
|
[Export] public double Duration { get; set; } = 30.0;
|
||||||
|
|
||||||
public override void Execute(GameState gameState)
|
public override void Execute(GameState gameState)
|
||||||
{
|
{
|
||||||
|
if (gameState.IsBuffActive(BuffId))
|
||||||
|
{
|
||||||
|
GD.Print($"Buff '{BuffId}' is already active. Cannot apply again.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var newBuff = new Buff
|
var newBuff = new Buff
|
||||||
{
|
{
|
||||||
Name = $"{TargetStat} x{Multiplier}",
|
Name = $"{TargetStat} x{Multiplier}",
|
||||||
Multiplier = Multiplier,
|
Multiplier = Multiplier,
|
||||||
Duration = Duration
|
Duration = Duration,
|
||||||
|
TargetStat = TargetStat,
|
||||||
|
BuffId = BuffId
|
||||||
};
|
};
|
||||||
|
|
||||||
gameState.ActiveBuffs.Add(newBuff);
|
gameState.ActiveBuffs.Add(newBuff);
|
||||||
|
gameState.AddActiveBuff(BuffId);
|
||||||
GameBus.Instance.NotifyBuffAdded(newBuff);
|
GameBus.Instance.NotifyBuffAdded(newBuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,8 +4,10 @@ namespace ParasiticGod.Scripts.Core.Effects;
|
|||||||
|
|
||||||
public class Buff
|
public class Buff
|
||||||
{
|
{
|
||||||
public Guid Id { get; } = Guid.NewGuid(); // Unique identifier
|
public Guid InstanceId { get; } = Guid.NewGuid();
|
||||||
public string Name { get; set; } // For display purposes
|
public string BuffId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public Stat TargetStat { get; set; }
|
||||||
public float Multiplier { get; set; } = 1.0f;
|
public float Multiplier { get; set; } = 1.0f;
|
||||||
public double Duration { get; set; }
|
public double Duration { get; set; }
|
||||||
}
|
}
|
22
Scripts/Core/EventDefinition.cs
Normal file
22
Scripts/Core/EventDefinition.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
using ParasiticGod.Scripts.Core.Effects;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts.Core;
|
||||||
|
|
||||||
|
public class EventDefinition
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public int MeanTimeToHappen { get; set; }
|
||||||
|
public EventTriggerDto Trigger { get; set; }
|
||||||
|
public List<EventOptionDefinition> Options { get; set; } = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EventOptionDefinition
|
||||||
|
{
|
||||||
|
public string Text { get; set; }
|
||||||
|
public string Tooltip { get; set; }
|
||||||
|
public Array<Effect> Effects { get; set; }
|
||||||
|
}
|
1
Scripts/Core/EventDefinition.cs.uid
Normal file
1
Scripts/Core/EventDefinition.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://ilyr01u70ciw
|
46
Scripts/Core/EventDto.cs
Normal file
46
Scripts/Core/EventDto.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts.Core;
|
||||||
|
|
||||||
|
public class EventTriggerDto
|
||||||
|
{
|
||||||
|
[JsonProperty("minFollowers")]
|
||||||
|
public long MinFollowers { get; set; } = 0;
|
||||||
|
|
||||||
|
[JsonProperty("maxCorruption")]
|
||||||
|
public double MaxCorruption { get; set; } = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EventOptionDto
|
||||||
|
{
|
||||||
|
[JsonProperty("text")]
|
||||||
|
public string Text { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("tooltip")]
|
||||||
|
public string Tooltip { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("effects")]
|
||||||
|
public List<EffectDto> Effects { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EventDto
|
||||||
|
{
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("title")]
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("description")]
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("meanTimeToHappen")]
|
||||||
|
public int MeanTimeToHappen { get; set; } = 100; // in game days
|
||||||
|
|
||||||
|
[JsonProperty("trigger")]
|
||||||
|
public EventTriggerDto Trigger { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("options")]
|
||||||
|
public List<EventOptionDto> Options { get; set; }
|
||||||
|
}
|
1
Scripts/Core/EventDto.cs.uid
Normal file
1
Scripts/Core/EventDto.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://nwwqn028soa5
|
71
Scripts/Core/EventLoader.cs
Normal file
71
Scripts/Core/EventLoader.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts.Core;
|
||||||
|
|
||||||
|
public static class EventLoader
|
||||||
|
{
|
||||||
|
public static List<EventDefinition> LoadAllEvents()
|
||||||
|
{
|
||||||
|
var loadedEvents = new Dictionary<string, EventDefinition>();
|
||||||
|
|
||||||
|
LoadEventsFromPath("res://Mods/Events", loadedEvents);
|
||||||
|
LoadEventsFromPath("user://Mods/Events", loadedEvents);
|
||||||
|
|
||||||
|
GD.Print($"Finished loading. Total unique events: {loadedEvents.Count}");
|
||||||
|
return new List<EventDefinition>(loadedEvents.Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoadEventsFromPath(string path, Dictionary<string, EventDefinition> events)
|
||||||
|
{
|
||||||
|
if (!DirAccess.DirExistsAbsolute(path)) return;
|
||||||
|
|
||||||
|
using var dir = DirAccess.Open(path);
|
||||||
|
dir.ListDirBegin();
|
||||||
|
var fileName = dir.GetNext();
|
||||||
|
while (!string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
if (!dir.CurrentIsDir() && fileName.EndsWith(".json"))
|
||||||
|
{
|
||||||
|
var filePath = path.PathJoin(fileName);
|
||||||
|
var ev = LoadEventFromFile(filePath);
|
||||||
|
if (ev != null)
|
||||||
|
{
|
||||||
|
events[ev.Id] = ev; // Add or overwrite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileName = dir.GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EventDefinition LoadEventFromFile(string filePath)
|
||||||
|
{
|
||||||
|
var fileContent = FileAccess.GetFileAsString(filePath);
|
||||||
|
if (string.IsNullOrEmpty(fileContent)) return null;
|
||||||
|
|
||||||
|
var dto = JsonConvert.DeserializeObject<EventDto>(fileContent);
|
||||||
|
if (dto == null) return null;
|
||||||
|
|
||||||
|
var eventDef = new EventDefinition
|
||||||
|
{
|
||||||
|
Id = dto.Id,
|
||||||
|
Title = dto.Title,
|
||||||
|
Description = dto.Description,
|
||||||
|
MeanTimeToHappen = dto.MeanTimeToHappen,
|
||||||
|
Trigger = dto.Trigger
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var optionDto in dto.Options)
|
||||||
|
{
|
||||||
|
var optionDef = new EventOptionDefinition
|
||||||
|
{
|
||||||
|
Text = optionDto.Text,
|
||||||
|
Tooltip = optionDto.Tooltip,
|
||||||
|
Effects = MiracleLoader.ConvertEffectDtos(optionDto.Effects)
|
||||||
|
};
|
||||||
|
eventDef.Options.Add(optionDef);
|
||||||
|
}
|
||||||
|
return eventDef;
|
||||||
|
}
|
||||||
|
}
|
1
Scripts/Core/EventLoader.cs.uid
Normal file
1
Scripts/Core/EventLoader.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://ceimix3ejnadj
|
@@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Godot;
|
||||||
using ParasiticGod.Scripts.Singletons;
|
using ParasiticGod.Scripts.Singletons;
|
||||||
|
|
||||||
namespace ParasiticGod.Scripts.Core;
|
namespace ParasiticGod.Scripts.Core;
|
||||||
@@ -12,11 +14,38 @@ public class GameLogic
|
|||||||
{
|
{
|
||||||
totalMultiplier *= buff.Multiplier;
|
totalMultiplier *= buff.Multiplier;
|
||||||
}
|
}
|
||||||
var faithPerSecond = state.Get(Stat.Followers) * state.Get(Stat.FaithPerFollower) * totalMultiplier;
|
|
||||||
|
var faithMultiplier = state.ActiveBuffs
|
||||||
|
.Where(b => b.TargetStat == Stat.FaithPerFollower)
|
||||||
|
.Aggregate(1.0f, (acc, buff) => acc * buff.Multiplier);
|
||||||
|
|
||||||
|
var productionFollowerMultiplier = state.ActiveBuffs
|
||||||
|
.Where(b => b.TargetStat == Stat.ProductionPerFollower)
|
||||||
|
.Aggregate(1.0f, (acc, buff) => acc * buff.Multiplier);
|
||||||
|
var productionFlatMultiplier = state.ActiveBuffs
|
||||||
|
.Where(b => b.TargetStat == Stat.ProductionPerSecond)
|
||||||
|
.Aggregate(1.0f, (acc, buff) => acc * buff.Multiplier);
|
||||||
|
|
||||||
|
var followerMultiplier = state.ActiveBuffs
|
||||||
|
.Where(b => b.TargetStat == Stat.FollowersPerSecond)
|
||||||
|
.Aggregate(1.0f, (acc, buff) => acc * buff.Multiplier);
|
||||||
|
var corruptionMultiplier = state.ActiveBuffs
|
||||||
|
.Where(b => b.TargetStat == Stat.CorruptionPerSecond)
|
||||||
|
.Aggregate(1.0f, (acc, buff) => acc * buff.Multiplier);
|
||||||
|
|
||||||
|
var faithPerSecond = state.Get(Stat.Followers) * state.Get(Stat.FaithPerFollower) * faithMultiplier;
|
||||||
|
|
||||||
|
var productionFromFollowers = state.Get(Stat.Followers) * state.Get(Stat.ProductionPerFollower) * productionFollowerMultiplier;
|
||||||
|
var productionFromIndustry = state.Get(Stat.ProductionPerSecond) * productionFlatMultiplier;
|
||||||
|
var totalProductionPerSecond = productionFromFollowers + productionFromIndustry;
|
||||||
|
|
||||||
|
var followersPerSecond = state.Get(Stat.FollowersPerSecond) * followerMultiplier;
|
||||||
|
var corruptionPerSecond = state.Get(Stat.CorruptionPerSecond) * corruptionMultiplier;
|
||||||
|
|
||||||
state.Modify(Stat.Faith, faithPerSecond * delta);
|
state.Modify(Stat.Faith, faithPerSecond * delta);
|
||||||
state.Modify(Stat.Production, state.Get(Stat.ProductionPerSecond) * delta);
|
state.Modify(Stat.Production, totalProductionPerSecond * delta);
|
||||||
state.Modify(Stat.Corruption, state.Get(Stat.CorruptionPerSecond) * delta);
|
state.Modify(Stat.Corruption, corruptionPerSecond * delta);
|
||||||
|
state.Modify(Stat.Followers, followersPerSecond * delta);
|
||||||
|
|
||||||
for (var i = state.ActiveBuffs.Count - 1; i >= 0; i--)
|
for (var i = state.ActiveBuffs.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -26,6 +55,7 @@ public class GameLogic
|
|||||||
{
|
{
|
||||||
GameBus.Instance.NotifyBuffRemoved(buff);
|
GameBus.Instance.NotifyBuffRemoved(buff);
|
||||||
state.ActiveBuffs.RemoveAt(i);
|
state.ActiveBuffs.RemoveAt(i);
|
||||||
|
state.RemoveActiveBuff(buff.BuffId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using ParasiticGod.Scripts.Core.Effects;
|
using ParasiticGod.Scripts.Core.Effects;
|
||||||
|
using static System.Double;
|
||||||
|
|
||||||
namespace ParasiticGod.Scripts.Core;
|
namespace ParasiticGod.Scripts.Core;
|
||||||
|
|
||||||
@@ -8,6 +9,7 @@ public class GameState
|
|||||||
{
|
{
|
||||||
private readonly Dictionary<Stat, StatData> _stats = new();
|
private readonly Dictionary<Stat, StatData> _stats = new();
|
||||||
private readonly HashSet<string> _unlockedMiracleIds = [];
|
private readonly HashSet<string> _unlockedMiracleIds = [];
|
||||||
|
private readonly HashSet<string> _activeBuffIds = [];
|
||||||
|
|
||||||
public List<Buff> ActiveBuffs { get; } = [];
|
public List<Buff> ActiveBuffs { get; } = [];
|
||||||
|
|
||||||
@@ -23,11 +25,13 @@ public class GameState
|
|||||||
Set(Stat.FaithPerFollower, 0.5);
|
Set(Stat.FaithPerFollower, 0.5);
|
||||||
Set(Stat.ProductionPerSecond, 0.0);
|
Set(Stat.ProductionPerSecond, 0.0);
|
||||||
Set(Stat.CorruptionPerSecond, 0.01);
|
Set(Stat.CorruptionPerSecond, 0.01);
|
||||||
|
Set(Stat.FollowersPerSecond, 0);
|
||||||
|
Set(Stat.ProductionPerFollower, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double Get(Stat stat) => _stats[stat].Value;
|
public double Get(Stat stat) => _stats[stat].Value;
|
||||||
|
|
||||||
public void Set(Stat stat, double value) => _stats[stat].Set(value);
|
public void Set(Stat stat, double value) => _stats[stat].Set(Math.Clamp(value, 0, MaxValue));
|
||||||
|
|
||||||
public void Modify(Stat stat, double delta) => _stats[stat].Set(Get(stat) + delta);
|
public void Modify(Stat stat, double delta) => _stats[stat].Set(Get(stat) + delta);
|
||||||
|
|
||||||
@@ -38,4 +42,8 @@ public class GameState
|
|||||||
public bool IsMiracleUnlocked(string miracleId) => _unlockedMiracleIds.Contains(miracleId);
|
public bool IsMiracleUnlocked(string miracleId) => _unlockedMiracleIds.Contains(miracleId);
|
||||||
public void AddUnlockedMiracle(string miracleId) => _unlockedMiracleIds.Add(miracleId);
|
public void AddUnlockedMiracle(string miracleId) => _unlockedMiracleIds.Add(miracleId);
|
||||||
public void RemoveUnlockedMiracle(string miracleId) => _unlockedMiracleIds.Remove(miracleId);
|
public void RemoveUnlockedMiracle(string miracleId) => _unlockedMiracleIds.Remove(miracleId);
|
||||||
|
|
||||||
|
public bool IsBuffActive(string buffId) => _activeBuffIds.Contains(buffId);
|
||||||
|
public void AddActiveBuff(string buffId) => _activeBuffIds.Add(buffId);
|
||||||
|
public void RemoveActiveBuff(string buffId) => _activeBuffIds.Remove(buffId);
|
||||||
}
|
}
|
@@ -12,6 +12,7 @@ public class EffectDto
|
|||||||
public double Value { get; set; }
|
public double Value { get; set; }
|
||||||
|
|
||||||
// --- For "ApplyBuff" Effect ---
|
// --- For "ApplyBuff" Effect ---
|
||||||
|
public string BuffId { get; set; }
|
||||||
public float Multiplier { get; set; }
|
public float Multiplier { get; set; }
|
||||||
public double Duration { get; set; }
|
public double Duration { get; set; }
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Godot.Collections;
|
using Godot.Collections;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -86,7 +87,17 @@ public static class MiracleLoader
|
|||||||
Effects = []
|
Effects = []
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var effectDto in miracleDto.Effects)
|
var effects = ConvertEffectDtos(miracleDto.Effects);
|
||||||
|
miracleDef.Effects = effects;
|
||||||
|
return miracleDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Array<Effect> ConvertEffectDtos(List<EffectDto> dtos)
|
||||||
|
{
|
||||||
|
var effects = new Array<Effect>();
|
||||||
|
if (dtos == null) return effects;
|
||||||
|
|
||||||
|
foreach (var effectDto in dtos)
|
||||||
{
|
{
|
||||||
if (EffectRegistry.TryGetValue(effectDto.Type, out var effectType))
|
if (EffectRegistry.TryGetValue(effectDto.Type, out var effectType))
|
||||||
{
|
{
|
||||||
@@ -101,6 +112,7 @@ public static class MiracleLoader
|
|||||||
applyBuffEffect.TargetStat = effectDto.TargetStat;
|
applyBuffEffect.TargetStat = effectDto.TargetStat;
|
||||||
applyBuffEffect.Multiplier = effectDto.Multiplier;
|
applyBuffEffect.Multiplier = effectDto.Multiplier;
|
||||||
applyBuffEffect.Duration = effectDto.Duration;
|
applyBuffEffect.Duration = effectDto.Duration;
|
||||||
|
applyBuffEffect.BuffId = effectDto.BuffId;
|
||||||
break;
|
break;
|
||||||
case ConvertResourceEffect convertResourceEffect:
|
case ConvertResourceEffect convertResourceEffect:
|
||||||
convertResourceEffect.FromResource = effectDto.FromResource;
|
convertResourceEffect.FromResource = effectDto.FromResource;
|
||||||
@@ -117,11 +129,9 @@ public static class MiracleLoader
|
|||||||
unlockMiracleEffect.MiraclesToUnlock = new Array<string>(effectDto.MiraclesToUnlock);
|
unlockMiracleEffect.MiraclesToUnlock = new Array<string>(effectDto.MiraclesToUnlock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
effects.Add(effectInstance);
|
||||||
miracleDef.Effects.Add(effectInstance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return effects;
|
||||||
return miracleDef;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -11,7 +11,9 @@ public enum Stat
|
|||||||
// Passive Generation Stats
|
// Passive Generation Stats
|
||||||
ProductionPerSecond,
|
ProductionPerSecond,
|
||||||
CorruptionPerSecond,
|
CorruptionPerSecond,
|
||||||
|
FollowersPerSecond,
|
||||||
|
|
||||||
// Modifying Stats
|
// Modifying Stats
|
||||||
FaithPerFollower
|
FaithPerFollower,
|
||||||
|
ProductionPerFollower,
|
||||||
}
|
}
|
12
Scripts/DisableMainThemeMusic.cs
Normal file
12
Scripts/DisableMainThemeMusic.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts;
|
||||||
|
|
||||||
|
public partial class DisableMainThemeMusic : Node
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
var mainThemeMusic = GetNodeOrNull<AudioStreamPlayer>("/root/MainThemeMusic");
|
||||||
|
mainThemeMusic?.Stop();
|
||||||
|
}
|
||||||
|
}
|
1
Scripts/DisableMainThemeMusic.cs.uid
Normal file
1
Scripts/DisableMainThemeMusic.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bif3eyfa1lgl4
|
15
Scripts/EnableMainThemeMusic.cs
Normal file
15
Scripts/EnableMainThemeMusic.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts;
|
||||||
|
|
||||||
|
public partial class EnableMainThemeMusic : Node
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
var mainThemeMusic = GetNodeOrNull<AudioStreamPlayer>("/root/MainThemeMusic");
|
||||||
|
if (mainThemeMusic is { Playing: false })
|
||||||
|
{
|
||||||
|
mainThemeMusic.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
Scripts/EnableMainThemeMusic.cs.uid
Normal file
1
Scripts/EnableMainThemeMusic.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dvmrpbba7plsf
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Godot.Collections;
|
||||||
using Limbo.Console.Sharp;
|
using Limbo.Console.Sharp;
|
||||||
using ParasiticGod.Scripts.Core;
|
using ParasiticGod.Scripts.Core;
|
||||||
using ParasiticGod.Scripts.Core.Effects;
|
using ParasiticGod.Scripts.Core.Effects;
|
||||||
@@ -10,9 +11,11 @@ namespace ParasiticGod.Scripts.Singletons;
|
|||||||
public partial class GameBus : Node
|
public partial class GameBus : Node
|
||||||
{
|
{
|
||||||
public static GameBus Instance { get; private set; }
|
public static GameBus Instance { get; private set; }
|
||||||
public Dictionary<string, MiracleDefinition> AllMiracles { get; private set; }
|
public System.Collections.Generic.Dictionary<string, MiracleDefinition> AllMiracles { get; private set; }
|
||||||
public List<TierDefinition> FollowerTiers { get; private set; }
|
public List<TierDefinition> FollowerTiers { get; private set; }
|
||||||
public List<TierDefinition> HutTiers { get; private set; }
|
public List<TierDefinition> HutTiers { get; private set; }
|
||||||
|
public List<TierDefinition> TempleTiers { get; private set; }
|
||||||
|
public List<EventDefinition> AllEvents { get; private set; }
|
||||||
|
|
||||||
private PackedScene _gameOverScene = GD.Load<PackedScene>("res://Scenes/game_over.tscn");
|
private PackedScene _gameOverScene = GD.Load<PackedScene>("res://Scenes/game_over.tscn");
|
||||||
private PackedScene _winScene = GD.Load<PackedScene>("res://Scenes/win_screen.tscn");
|
private PackedScene _winScene = GD.Load<PackedScene>("res://Scenes/win_screen.tscn");
|
||||||
@@ -29,13 +32,16 @@ public partial class GameBus : Node
|
|||||||
public event Action PopulationVisualsUpdated;
|
public event Action PopulationVisualsUpdated;
|
||||||
public event Action<string> AgeAdvanced;
|
public event Action<string> AgeAdvanced;
|
||||||
public event Action GameWon;
|
public event Action GameWon;
|
||||||
|
public event Action<bool> PauseStateChanged;
|
||||||
|
|
||||||
public override void _EnterTree()
|
public override void _EnterTree()
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
AllMiracles = MiracleLoader.LoadAllMiracles();
|
AllMiracles = MiracleLoader.LoadAllMiracles();
|
||||||
|
AllEvents = EventLoader.LoadAllEvents();
|
||||||
FollowerTiers = TierLoader.LoadTiers("res://Mods/Tiers/follower_tiers.json", "user://Mods/Tiers/follower_tiers.json");
|
FollowerTiers = TierLoader.LoadTiers("res://Mods/Tiers/follower_tiers.json", "user://Mods/Tiers/follower_tiers.json");
|
||||||
HutTiers = TierLoader.LoadTiers("res://Mods/Tiers/hut_tiers.json","user://Mods/Tiers/hut_tiers.json");
|
HutTiers = TierLoader.LoadTiers("res://Mods/Tiers/hut_tiers.json","user://Mods/Tiers/hut_tiers.json");
|
||||||
|
TempleTiers = TierLoader.LoadTiers("res://Mods/Tiers/temple_tiers.json","user://Mods/Tiers/temple_tiers.json");
|
||||||
|
|
||||||
GameWon += OnGameWon;
|
GameWon += OnGameWon;
|
||||||
}
|
}
|
||||||
@@ -122,9 +128,24 @@ public partial class GameBus : Node
|
|||||||
GameWon?.Invoke();
|
GameWon?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ExecuteEffects(Array<Effect> effects)
|
||||||
|
{
|
||||||
|
foreach (var effect in effects)
|
||||||
|
{
|
||||||
|
effect.Execute(_gameState);
|
||||||
|
}
|
||||||
|
SetPause(false);
|
||||||
|
}
|
||||||
|
|
||||||
public void SubscribeToStat(Stat stat, Action<double> listener) => _gameState.Subscribe(stat, listener);
|
public void SubscribeToStat(Stat stat, Action<double> listener) => _gameState.Subscribe(stat, listener);
|
||||||
public void UnsubscribeFromStat(Stat stat, Action<double> listener) => _gameState.Unsubscribe(stat, listener);
|
public void UnsubscribeFromStat(Stat stat, Action<double> listener) => _gameState.Unsubscribe(stat, listener);
|
||||||
|
|
||||||
|
public void SetPause(bool isPaused)
|
||||||
|
{
|
||||||
|
GetTree().Paused = isPaused;
|
||||||
|
PauseStateChanged?.Invoke(isPaused);
|
||||||
|
}
|
||||||
|
|
||||||
public GameState CurrentState => _gameState;
|
public GameState CurrentState => _gameState;
|
||||||
|
|
||||||
[ConsoleCommand("set_stat", "Sets the value of a specified stat.")]
|
[ConsoleCommand("set_stat", "Sets the value of a specified stat.")]
|
||||||
|
76
Scripts/UI/EventPopup.cs
Normal file
76
Scripts/UI/EventPopup.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using Godot;
|
||||||
|
using ParasiticGod.Scripts.Core;
|
||||||
|
using ParasiticGod.Scripts.Singletons;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts.UI;
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class EventPopup : PanelContainer
|
||||||
|
{
|
||||||
|
[Export] private Label _titleLabel;
|
||||||
|
[Export] private RichTextLabel _descriptionLabel;
|
||||||
|
[Export] private VBoxContainer _optionsContainer;
|
||||||
|
[Export] private PackedScene _optionButtonScene; // A scene for a single button
|
||||||
|
[Export] private float _choiceTimeout = 30.0f;
|
||||||
|
|
||||||
|
private EventDefinition _eventDef;
|
||||||
|
private Timer _timeoutTimer;
|
||||||
|
private readonly RandomNumberGenerator _rng = new();
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
ProcessMode = ProcessModeEnum.Always;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisplayEvent(EventDefinition eventDef)
|
||||||
|
{
|
||||||
|
_eventDef = eventDef;
|
||||||
|
_titleLabel.Text = eventDef.Title;
|
||||||
|
_descriptionLabel.Text = eventDef.Description;
|
||||||
|
|
||||||
|
foreach (var child in _optionsContainer.GetChildren())
|
||||||
|
{
|
||||||
|
child.QueueFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var option in eventDef.Options)
|
||||||
|
{
|
||||||
|
var button = _optionButtonScene.Instantiate<Button>();
|
||||||
|
button.Text = option.Text;
|
||||||
|
button.TooltipText = option.Tooltip;
|
||||||
|
|
||||||
|
button.Pressed += () =>
|
||||||
|
{
|
||||||
|
_timeoutTimer.Stop();
|
||||||
|
HandleChoice(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
_optionsContainer.AddChild(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
_timeoutTimer = new Timer { WaitTime = _choiceTimeout, OneShot = true };
|
||||||
|
AddChild(_timeoutTimer);
|
||||||
|
_timeoutTimer.Timeout += OnTimeout;
|
||||||
|
_timeoutTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTimeout()
|
||||||
|
{
|
||||||
|
if (_eventDef.Options.Count > 0)
|
||||||
|
{
|
||||||
|
var randomIndex = _rng.RandiRange(0, _eventDef.Options.Count - 1);
|
||||||
|
HandleChoice(_eventDef.Options[randomIndex]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QueueFree();
|
||||||
|
GetTree().Paused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleChoice(EventOptionDefinition option)
|
||||||
|
{
|
||||||
|
GameBus.Instance.ExecuteEffects(option.Effects);
|
||||||
|
QueueFree();
|
||||||
|
}
|
||||||
|
}
|
1
Scripts/UI/EventPopup.cs.uid
Normal file
1
Scripts/UI/EventPopup.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://h1x5eqt0lc5m
|
29
Scripts/UI/TutorialScene.cs
Normal file
29
Scripts/UI/TutorialScene.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using DialogueManagerRuntime;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace ParasiticGod.Scripts.UI;
|
||||||
|
|
||||||
|
public partial class TutorialScene : Control
|
||||||
|
{
|
||||||
|
[Export] private PackedScene _mainGameScene;
|
||||||
|
[Export] private Resource _tutorialDialogue;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
DialogueManager.DialogueEnded += OnDialogueEnded;
|
||||||
|
DialogueManager.ShowExampleDialogueBalloon(_tutorialDialogue, "start");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
DialogueManager.DialogueEnded -= OnDialogueEnded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDialogueEnded(Resource resource)
|
||||||
|
{
|
||||||
|
if (resource == _tutorialDialogue)
|
||||||
|
{
|
||||||
|
GetTree().ChangeSceneToPacked(_mainGameScene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
Scripts/UI/TutorialScene.cs.uid
Normal file
1
Scripts/UI/TutorialScene.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://d08d3pi7sx8k3
|
BIN
Sfx/Ascend Beyond.mp3
Normal file
BIN
Sfx/Ascend Beyond.mp3
Normal file
Binary file not shown.
19
Sfx/Ascend Beyond.mp3.import
Normal file
19
Sfx/Ascend Beyond.mp3.import
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://46kqkf4ckqek"
|
||||||
|
path="res://.godot/imported/Ascend Beyond.mp3-225c648bac3dc986f75992f9d3ccb96d.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Sfx/Ascend Beyond.mp3"
|
||||||
|
dest_files=["res://.godot/imported/Ascend Beyond.mp3-225c648bac3dc986f75992f9d3ccb96d.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
BIN
Sfx/MainTheme.mp3
Normal file
BIN
Sfx/MainTheme.mp3
Normal file
Binary file not shown.
19
Sfx/MainTheme.mp3.import
Normal file
19
Sfx/MainTheme.mp3.import
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://wm3vocs0kkk8"
|
||||||
|
path="res://.godot/imported/MainTheme.mp3-212a5702d6d6fce08090316bf842178d.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Sfx/MainTheme.mp3"
|
||||||
|
dest_files=["res://.godot/imported/MainTheme.mp3-212a5702d6d6fce08090316bf842178d.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
BIN
Sfx/The Hollow Throne.mp3
Normal file
BIN
Sfx/The Hollow Throne.mp3
Normal file
Binary file not shown.
19
Sfx/The Hollow Throne.mp3.import
Normal file
19
Sfx/The Hollow Throne.mp3.import
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://defdxbv24q6l1"
|
||||||
|
path="res://.godot/imported/The Hollow Throne.mp3-2205b1087f253cf81b97a8caaea58efc.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Sfx/The Hollow Throne.mp3"
|
||||||
|
dest_files=["res://.godot/imported/The Hollow Throne.mp3-2205b1087f253cf81b97a8caaea58efc.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://cx3lujtdnjgbd"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_1.wav-7cbb56ae27212293a53b44b25ca63aa1.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_1.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_1.wav-7cbb56ae27212293a53b44b25ca63aa1.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://d1ojjdhkye60a"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_10.wav-90ddfa78058d85aa9ad63fff5c97ca16.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_10.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_10.wav-90ddfa78058d85aa9ad63fff5c97ca16.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://rqiatqrim2ej"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_11.wav-7e6ae22c23408d14e8e5f12526df9be6.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_11.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_11.wav-7e6ae22c23408d14e8e5f12526df9be6.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://s13wrqeinabo"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_12.wav-c64d956571bc7960f7f3021c8c047031.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_12.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_12.wav-c64d956571bc7960f7f3021c8c047031.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://bdauyaf3m1ii6"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_13.wav-b432c83d18ec2528b5dd55c9e6eb6e26.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_13.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_13.wav-b432c83d18ec2528b5dd55c9e6eb6e26.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://b3tiilkhxedmc"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_14.wav-4b60ebf5c2442a0bbbd4db41353e2797.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_14.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_14.wav-4b60ebf5c2442a0bbbd4db41353e2797.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://blic15k83hbp5"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_15.wav-9a647996664e80a0d3942b61168ce672.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_15.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_15.wav-9a647996664e80a0d3942b61168ce672.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://c4632bogkmg5h"
|
|
||||||
path="res://.godot/imported/UI_SFX_Pack_61_16.wav-76d966d41c556ba7145673f9724f6af7.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://Sfx/UI_SFX_Pack_61_16.wav"
|
|
||||||
dest_files=["res://.godot/imported/UI_SFX_Pack_61_16.wav-76d966d41c556ba7145673f9724f6af7.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=0
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user