diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 3f87958..a0df654 100644
Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ
diff --git a/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml b/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml
index d8d7fea..e382989 100644
--- a/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml
+++ b/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml
@@ -943,22 +943,30 @@
false
false
- Verb_AbilityShoot
- Bullet_ARA_MimicNematode_Needle
+ Verb_CastAbility
5
+ 0.1
Heatspikes_Shot
Heatspikes_Tail
- 9
- 2
- 0
- 32
- 1
- 1
- 1
- 1
- false
+ false
+ false
+
+ true
+
+
+
+ Bullet_ARA_MimicNematode_Needle
+ 32
+
+
+ 1
+ true
+ true
+ false
+ 3
+
饮食
true
@@ -975,6 +983,52 @@
+
+ ARA_SymbioticStabilizer
+ 拟线控制
+ 向目标注射阿拉克涅拟线种的控制溶液,溶液将保证目标不会因为阿拉克涅拟线种在体内的扩散而死亡。
+ ArachnaeSwarm/UI/Abilities/ARA_Dissolver_Touch
+ 6000
+ 5
+ true
+ false
+ false
+ true
+ true
+
+ CastAbilityOnThingMelee
+
+ Verb_CastAbilityTouch
+ false
+ false
+ 0.5
+ -1
+ false
+ AcidSpray_Resolve
+
+ true
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+ 饮食
+ true
+ Food
+ 0.2
+ 营养值不足,需要进食
+
+
+ CompAbilityEffect_GiveHediff
+ ARA_SymbioticStabilizer
+ true
+
+
+
Bullet_ARA_MimicNematode_Needle
拟线种寄生针
diff --git a/1.6/1.6/Defs/EventDefs/ARA_Loop_Attack_EventDef.xml b/1.6/1.6/Defs/EventDefs/ARA_Loop_Attack_EventDef.xml
deleted file mode 100644
index 1ee7017..0000000
--- a/1.6/1.6/Defs/EventDefs/ARA_Loop_Attack_EventDef.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
- ARA_Loop_Raid_Incident
- 虫群袭击
- Misc
-
- Map_PlayerHome
-
-
-
- IncidentWorker_GiveQuest
-
-
- ARA_Loop_Raid_Quest
-
-
-
-
- ARA_Loop_Raid_Quest
- 虫群袭击
- 虫群袭击description
-
-
-
-
-
- questName->虫群袭击
-
-
-
-
-
-
- questDescription->虫群袭击questDescription
-
-
-
-
- 虫群袭击Label
- 虫群袭击Title
- 虫群袭击Text
-
-
- 袭击开始
-
-
-
-
- ARA_Loop_Raid_Main_Event_1
-
-
-
-
-
-
-
-
-
-
-
- ARA_Loop_Raid_Main_Event_1
- 嘻嘻
- true
-
-
-
-
-
- 10000
- ARA_Hostile_Hive
- ImmediateAttack
- EdgeWalkIn
- Combat
-
-
- Combat
- 100
-
- 7
- 3
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml
index d27a295..d1e0a0c 100644
--- a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml
+++ b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml
@@ -221,6 +221,7 @@
ARA_MimicNematode_Needle_Fire
+ ARA_SymbioticStabilizer
diff --git a/1.6/1.6/Defs/MiscSettingDefs/EventUIConfig.xml b/1.6/1.6/Defs/MiscSettingDefs/EventUIConfig.xml
deleted file mode 100644
index b77c771..0000000
--- a/1.6/1.6/Defs/MiscSettingDefs/EventUIConfig.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
- ARA_EventUIConfig
-
-
- Small
- false
- false
- true
-
-
-
- (500, 800)
- (650, 130)
- (650, 350)
- 750
-
-
- 0
- 0
-
- (750, 600)
-
-
- (200, 50)
- (600, 200)
- (600, 200)
- 600
- 20
- 20
- 20
-
-
-
-
diff --git a/1.6/1.6/Defs/MiscSettingDefs/LetterDefs/EventLetter.xml b/1.6/1.6/Defs/MiscSettingDefs/LetterDefs/EventLetter.xml
deleted file mode 100644
index bc59ea7..0000000
--- a/1.6/1.6/Defs/MiscSettingDefs/LetterDefs/EventLetter.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- ARA_EventChoiceLetter
- ArachnaeSwarm.Letter_EventChoice
- LetterArrive_Good
- (120, 150, 255)
-
-
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
index 6f5a3a1..93fd338 100644
--- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
+++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
@@ -774,6 +774,7 @@
ArachnaeMyrmecocystus_Body
2
+
@@ -927,6 +928,7 @@
1.5
3
+
@@ -1041,6 +1043,7 @@
ArachnaeWeaponSmith_Body
0.8
0.75
+
@@ -1187,6 +1190,7 @@
ArachnaeFighter_Body
0.7
3
+
@@ -1313,6 +1317,7 @@
ArachnaeFacehugger_Body
0.5
0.25
+
@@ -1394,6 +1399,7 @@
ArachnaeSmokepop_Body
4
+
@@ -1519,6 +1525,7 @@
1.0
2
+
@@ -1735,6 +1742,7 @@
1.0
0.8
2
+
@@ -1942,6 +1950,7 @@
ArachnaePraetorian_Body
2
3
+
diff --git a/1.6/1.6/Defs/Thing_Misc/ARA_Medicine.xml b/1.6/1.6/Defs/Thing_Misc/ARA_Medicine.xml
index f65bdd8..8265590 100644
--- a/1.6/1.6/Defs/Thing_Misc/ARA_Medicine.xml
+++ b/1.6/1.6/Defs/Thing_Misc/ARA_Medicine.xml
@@ -84,15 +84,15 @@
ARA_SymbioticStabilizer
信息素抑制
一种信息素抑制效果
- 阿拉克涅信息素溶剂的效果正在生效,它模拟了虫群的共生信号,抑制了体内寄生体的活性。在溶剂生效时,不会使得拟线种虫族寄生的进度超过80%。
+ 阿拉克涅信息素溶剂的效果正在生效,它模拟了虫群的共生信号,抑制了体内寄生体的活性,不会使得拟线种虫族寄生的进度超过80%。
HediffWithComps
(0.7, 1.0, 0.7)
false
-
- -0.34
+
diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo
index 7d00ae7..5bda578 100644
Binary files a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo and b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo differ
diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
index d3eb6a2..aceb529 100644
--- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
+++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
@@ -1,26 +1,42 @@
{
"Version": 1,
- "WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
+ "WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_fanshapedstunknockback\\safer_pawnflyer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_fanshapedstunknockback\\safer_pawnflyer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_feedwithhoney\\thinknode_jobgiver_feedwithhoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_feedwithhoney\\thinknode_jobgiver_feedwithhoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_fanshapedstunknockback\\compproperties_abilityfanshapedstunknockback.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_fanshapedstunknockback\\compproperties_abilityfanshapedstunknockback.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_plant\\thinknode_conditionalanimalshoulddogrowingwork.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_plant\\thinknode_conditionalanimalshoulddogrowingwork.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\compgestalt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\compgestalt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_clean\\thinknode_conditionalanimalshoulddocleaningwork.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_clean\\thinknode_conditionalanimalshoulddocleaningwork.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_spawner\\hediffcomp_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_spawner\\hediffcomp_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\arachnaelog.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:arachnaelog.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_trainingwork\\compadvancedtraining.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_trainingwork\\compadvancedtraining.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_showinteractivething\\compabilityeffect_showinteractivething.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showinteractivething\\compabilityeffect_showinteractivething.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\ara_defof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:ara_defof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_automechcarrier\\compautomechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_automechcarrier\\compautomechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_automechcarrier\\compproducedbymechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_automechcarrier\\compproducedbymechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -30,7 +46,7 @@
"DocumentGroups": [
{
"DockedWidth": 200,
- "SelectedChildIndex": 2,
+ "SelectedChildIndex": 1,
"Children": [
{
"$type": "Bookmark",
@@ -38,66 +54,120 @@
},
{
"$type": "Document",
- "DocumentIndex": 1,
- "Title": "CompProperties_AbilityFanShapedStunKnockback.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_FanShapedStunKnockback\\CompProperties_AbilityFanShapedStunKnockback.cs",
- "RelativeDocumentMoniker": "Abilities\\ARA_FanShapedStunKnockback\\CompProperties_AbilityFanShapedStunKnockback.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_FanShapedStunKnockback\\CompProperties_AbilityFanShapedStunKnockback.cs",
- "RelativeToolTip": "Abilities\\ARA_FanShapedStunKnockback\\CompProperties_AbilityFanShapedStunKnockback.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAAAMAAAAXAAAAAAAAAA==",
+ "DocumentIndex": 0,
+ "Title": "ThinkNode_JobGiver_FeedWithHoney.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_FeedWithHoney.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_FeedWithHoney.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_FeedWithHoney.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_FeedWithHoney.cs",
+ "ViewState": "AgIAAEsAAAAAAAAAAAAawGcAAAAZAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-03-27T07:30:03.977Z",
+ "WhenOpened": "2026-03-29T09:23:09.491Z",
"EditorCaption": ""
},
{
"$type": "Document",
- "DocumentIndex": 0,
- "Title": "Safer_PawnFlyer.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_FanShapedStunKnockback\\Safer_PawnFlyer.cs",
- "RelativeDocumentMoniker": "Abilities\\ARA_FanShapedStunKnockback\\Safer_PawnFlyer.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_FanShapedStunKnockback\\Safer_PawnFlyer.cs",
- "RelativeToolTip": "Abilities\\ARA_FanShapedStunKnockback\\Safer_PawnFlyer.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAAA0AAAAJAAAAAAAAAA==",
+ "DocumentIndex": 1,
+ "Title": "ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Plant\\ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_Plant\\ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Plant\\ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_Plant\\ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAABPAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-03-27T07:30:02.935Z",
+ "WhenOpened": "2026-03-29T09:22:20.81Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
- "Title": "CompGestalt.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\CompGestalt.cs",
- "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\CompGestalt.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\CompGestalt.cs",
- "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\CompGestalt.cs",
- "ViewState": "AgIAAEIAAAAAAAAAAAAQwD0AAABCAAAAAAAAAA==",
+ "Title": "ThinkNode_ConditionalAnimalShouldDoCleaningWork.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Clean\\ThinkNode_ConditionalAnimalShouldDoCleaningWork.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_Clean\\ThinkNode_ConditionalAnimalShouldDoCleaningWork.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Clean\\ThinkNode_ConditionalAnimalShouldDoCleaningWork.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_Clean\\ThinkNode_ConditionalAnimalShouldDoCleaningWork.cs",
+ "ViewState": "AgIAAAoAAAAAAAAAAAAAABEAAAAgAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-03-27T03:57:27.664Z",
+ "WhenOpened": "2026-03-29T09:22:16.941Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
- "Title": "Hediff_HiveMindMaster.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
- "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
- "RelativeToolTip": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
- "ViewState": "AgIAADQAAAAAAAAAAAAuwFkAAAAuAAAAAAAAAA==",
+ "Title": "HediffComp_Spawner.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
+ "RelativeDocumentMoniker": "Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
+ "RelativeToolTip": "Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAIcBAAAmAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-03-27T03:54:02.567Z"
+ "WhenOpened": "2026-03-29T09:22:11.004Z",
+ "EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
- "Title": "ArachnaeLog.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ArachnaeLog.cs",
- "RelativeDocumentMoniker": "ArachnaeLog.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ArachnaeLog.cs",
- "RelativeToolTip": "ArachnaeLog.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAANAAAAAAAAAA==",
+ "Title": "CompAdvancedTraining.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_TrainingWork\\CompAdvancedTraining.cs",
+ "RelativeDocumentMoniker": "Pawn_Comps\\ARA_TrainingWork\\CompAdvancedTraining.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_TrainingWork\\CompAdvancedTraining.cs",
+ "RelativeToolTip": "Pawn_Comps\\ARA_TrainingWork\\CompAdvancedTraining.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAwAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-03-26T06:10:50.583Z"
+ "WhenOpened": "2026-03-29T09:21:10.952Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 5,
+ "Title": "CompAbilityEffect_ShowInteractiveThing.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowInteractiveThing\\CompAbilityEffect_ShowInteractiveThing.cs",
+ "RelativeDocumentMoniker": "Abilities\\ARA_ShowInteractiveThing\\CompAbilityEffect_ShowInteractiveThing.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowInteractiveThing\\CompAbilityEffect_ShowInteractiveThing.cs",
+ "RelativeToolTip": "Abilities\\ARA_ShowInteractiveThing\\CompAbilityEffect_ShowInteractiveThing.cs",
+ "ViewState": "AgIAAD4AAAAAAAAAAAAAAFIAAAAiAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-03-29T09:21:03.275Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 6,
+ "Title": "ARA_DefOf.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs",
+ "RelativeDocumentMoniker": "ARA_DefOf.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs",
+ "RelativeToolTip": "ARA_DefOf.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAA4AAABAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-03-29T09:20:59.349Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 8,
+ "Title": "CompProducedByMechCarrier.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompProducedByMechCarrier.cs",
+ "RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\CompProducedByMechCarrier.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompProducedByMechCarrier.cs",
+ "RelativeToolTip": "Pawn_Comps\\ARA_AutoMechCarrier\\CompProducedByMechCarrier.cs",
+ "ViewState": "AgIAAJQAAAAAAAAAAAAowOoAAAARAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-03-29T09:06:28.908Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 7,
+ "Title": "CompAutoMechCarrier.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "RelativeToolTip": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "ViewState": "AgIAAIACAAAAAAAAAAAqwI8CAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-03-29T08:49:14.026Z",
+ "EditorCaption": ""
}
]
}
diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
index 0034ef3..81d8554 100644
--- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
+++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
@@ -238,19 +238,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Source/ArachnaeSwarm/EventSystem/CompOpenCustomUI.cs b/Source/ArachnaeSwarm/EventSystem/CompOpenCustomUI.cs
deleted file mode 100644
index 305ed1e..0000000
--- a/Source/ArachnaeSwarm/EventSystem/CompOpenCustomUI.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System; // Required for Activator
-using RimWorld;
-using Verse;
-using System.Collections.Generic;
-using Verse.AI;
-
-namespace ArachnaeSwarm
-{
- public class CompProperties_OpenCustomUI : CompProperties
- {
- public string uiDefName;
- public string label; // The text to display in the float menu
- public string failReason; // Optional: Custom text to show if the pawn can't reach the building
-
- public CompProperties_OpenCustomUI()
- {
- this.compClass = typeof(CompOpenCustomUI);
- }
- }
-
- public class CompOpenCustomUI : ThingComp
- {
- public CompProperties_OpenCustomUI Props => (CompProperties_OpenCustomUI)this.props;
-
- public override IEnumerable CompFloatMenuOptions(Pawn selPawn)
- {
- // Check if the pawn can interact with the building
- if (!selPawn.CanReserveAndReach(this.parent, PathEndMode.InteractionCell, Danger.Deadly))
- {
- string reason = Props.failReason ?? "CannotUseNoPath".Translate();
- yield return new FloatMenuOption(reason, null);
- yield break;
- }
-
- // Check for power if the building has a power component
- CompPowerTrader powerComp = this.parent.GetComp();
- if (powerComp != null && !powerComp.PowerOn)
- {
- yield return new FloatMenuOption("CannotUseNoPower".Translate(), null);
- yield break;
- }
-
- string label = Props.label ?? "Open Custom UI"; // Use default label if not provided
-
- FloatMenuOption option = new FloatMenuOption(label, delegate()
- {
- EventDef uiDef = DefDatabase.GetNamed(Props.uiDefName, false);
- if (uiDef != null)
- {
- Find.WindowStack.Add((Window)Activator.CreateInstance(uiDef.windowType, uiDef));
- }
- else
- {
- ArachnaeLog.Debug($"[CompOpenCustomUI] Could not find EventDef named '{Props.uiDefName}'.");
- }
- });
-
- yield return option;
- }
- }
-}
diff --git a/Source/ArachnaeSwarm/EventSystem/Condition.cs b/Source/ArachnaeSwarm/EventSystem/Condition.cs
deleted file mode 100644
index c8e8cc6..0000000
--- a/Source/ArachnaeSwarm/EventSystem/Condition.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-using Verse;
-using RimWorld;
-
-namespace ArachnaeSwarm
-{
- public abstract class Condition
- {
- public abstract bool IsMet(out string reason);
- }
-
- public class Condition_VariableEquals : Condition
- {
- public string name;
- public string value;
- public string valueVariableName;
-
- public override bool IsMet(out string reason)
- {
- var eventVarManager = Find.World.GetComponent();
- if (!eventVarManager.HasVariable(name))
- {
- reason = $"Variable '{name}' not found.";
- return false;
- }
-
- object variable = eventVarManager.GetVariable(name);
- string compareValueStr = value;
-
- if (!string.IsNullOrEmpty(valueVariableName))
- {
- compareValueStr = eventVarManager.GetVariable(valueVariableName)?.ToString();
- if (compareValueStr == null)
- {
- reason = $"Comparison variable '{valueVariableName}' not set.";
- return false;
- }
- }
-
- bool met = false;
- try
- {
- if (variable is int)
- {
- met = (int)variable == int.Parse(compareValueStr);
- }
- else if (variable is float)
- {
- met = (float)variable == float.Parse(compareValueStr);
- }
- else if (variable is bool)
- {
- met = (bool)variable == bool.Parse(compareValueStr);
- }
- else
- {
- met = variable?.ToString() == compareValueStr;
- }
- }
- catch (System.Exception e)
- {
- ArachnaeLog.Debug($"[EventSystem] Condition_VariableEquals: Could not compare '{variable}' and '{compareValueStr}'. Error: {e.Message}");
- reason = "Type mismatch or parsing error during comparison.";
- return false;
- }
-
- if (!met)
- {
- reason = $"Requires {name} = {compareValueStr} (Current: {variable})";
- }
- else
- {
- reason = "";
- }
- return met;
- }
- }
-
- public abstract class Condition_CompareVariable : Condition
- {
- public string name;
- public float value;
- public string valueVariableName;
-
- protected abstract bool Compare(float var1, float var2);
- protected abstract string GetOperatorString();
-
- public override bool IsMet(out string reason)
- {
- var eventVarManager = Find.World.GetComponent();
- if (!eventVarManager.HasVariable(name))
- {
- ArachnaeLog.Debug($"[EventSystem] {GetType().Name}: Variable '{name}' not found, defaulting to 0f.");
- eventVarManager.SetVariable(name, 0f);
- }
-
- float variable = eventVarManager.GetVariable(name);
-
- float compareValue = value;
- if (!string.IsNullOrEmpty(valueVariableName))
- {
- compareValue = eventVarManager.GetVariable(valueVariableName, float.NaN);
- if (float.IsNaN(compareValue))
- {
- reason = $"Comparison variable '{valueVariableName}' not set or not a number.";
- ArachnaeLog.Debug($"[EventSystem] {GetType().Name} check for '{name}' failed: {reason}");
- return false;
- }
- }
-
- bool met = Compare(variable, compareValue);
- ArachnaeLog.Debug($"[EventSystem] {GetType().Name} check: Name='{name}', CurrentValue='{variable}', CompareValue='{compareValue}', Met={met}");
- if (!met)
- {
- reason = $"Requires {name} {GetOperatorString()} {compareValue} (Current: {variable})";
- }
- else
- {
- reason = "";
- }
- return met;
- }
- }
-
- public class Condition_VariableGreaterThan : Condition_CompareVariable
- {
- protected override bool Compare(float var1, float var2) => var1 > var2;
- protected override string GetOperatorString() => ">";
- }
-
- public class Condition_VariableLessThan : Condition_CompareVariable
- {
- protected override bool Compare(float var1, float var2) => var1 < var2;
- protected override string GetOperatorString() => "<";
- }
-
- public class Condition_VariableGreaterThanOrEqual : Condition_CompareVariable
- {
- protected override bool Compare(float var1, float var2) => var1 >= var2;
- protected override string GetOperatorString() => ">=";
- }
-
- public class Condition_VariableLessThanOrEqual : Condition_CompareVariable
- {
- protected override bool Compare(float var1, float var2) => var1 <= var2;
- protected override string GetOperatorString() => "<=";
- }
-
- public class Condition_VariableNotEqual : Condition
- {
- public string name;
- public string value;
- public string valueVariableName;
-
- public override bool IsMet(out string reason)
- {
- var eventVarManager = Find.World.GetComponent();
- if (!eventVarManager.HasVariable(name))
- {
- reason = $"Variable '{name}' not found.";
- return false;
- }
-
- object variable = eventVarManager.GetVariable(name);
- string compareValueStr = value;
-
- if (!string.IsNullOrEmpty(valueVariableName))
- {
- compareValueStr = eventVarManager.GetVariable(valueVariableName)?.ToString();
- if (compareValueStr == null)
- {
- reason = $"Comparison variable '{valueVariableName}' not set.";
- return false;
- }
- }
-
- bool met = false;
- try
- {
- if (variable is int)
- {
- met = (int)variable != int.Parse(compareValueStr);
- }
- else if (variable is float)
- {
- met = (float)variable != float.Parse(compareValueStr);
- }
- else if (variable is bool)
- {
- met = (bool)variable != bool.Parse(compareValueStr);
- }
- else
- {
- met = variable?.ToString() != compareValueStr;
- }
- }
- catch (System.Exception e)
- {
- ArachnaeLog.Debug($"[EventSystem] Condition_VariableNotEqual: Could not compare '{variable}' and '{compareValueStr}'. Error: {e.Message}");
- reason = "Type mismatch or parsing error during comparison.";
- return false;
- }
-
- ArachnaeLog.Debug($"[EventSystem] Condition_VariableNotEqual check: Name='{name}', Type='{variable?.GetType().Name ?? "null"}', CurrentValue='{variable}', CompareValue='{compareValueStr}', Met={met}");
- if (!met)
- {
- reason = $"Requires {name} != {compareValueStr} (Current: {variable})";
- }
- else
- {
- reason = "";
- }
- return met;
- }
- }
-
- public class Condition_FactionExists : Condition
- {
- public FactionDef factionDef;
-
- public override bool IsMet(out string reason)
- {
- if (factionDef == null)
- {
- reason = "FactionDef not specified in Condition_FactionExists.";
- return false;
- }
-
- bool exists = Find.FactionManager.FirstFactionOfDef(factionDef) != null;
- if (!exists)
- {
- reason = $"Faction '{factionDef.label}' does not exist in the world.";
- }
- else
- {
- reason = "";
- }
- return exists;
- }
- }
-}
diff --git a/Source/ArachnaeSwarm/EventSystem/DebugActions.cs b/Source/ArachnaeSwarm/EventSystem/DebugActions.cs
deleted file mode 100644
index f3d597b..0000000
--- a/Source/ArachnaeSwarm/EventSystem/DebugActions.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using System; // Required for Activator
-using System.Collections.Generic;
-using LudeonTK;
-using Verse;
-using RimWorld;
-
-namespace ArachnaeSwarm
-{
- public static class WulaDebugActions
- {
- [DebugAction("Wula Fallen Empire", "Open Custom UI...", actionType = DebugActionType.Action, allowedGameStates = AllowedGameStates.Playing)]
- private static void OpenCustomUI()
- {
- List list = new List();
- foreach (EventDef localDef in DefDatabase.AllDefs)
- {
- EventDef currentDef = localDef;
- list.Add(new DebugMenuOption(currentDef.defName, DebugMenuOptionMode.Action, delegate
- {
- if (currentDef.hiddenWindow)
- {
- if (!currentDef.dismissEffects.NullOrEmpty())
- {
- foreach (var conditionalEffect in currentDef.dismissEffects)
- {
- string reason;
- bool conditionsMet = true;
- if (!conditionalEffect.conditions.NullOrEmpty())
- {
- foreach (var condition in conditionalEffect.conditions)
- {
- if (!condition.IsMet(out reason))
- {
- conditionsMet = false;
- break;
- }
- }
- }
-
- if (conditionsMet)
- {
- conditionalEffect.Execute(null);
- }
- }
- }
- }
- else
- {
- Find.WindowStack.Add((Window)Activator.CreateInstance(currentDef.windowType, currentDef));
- }
- }));
- }
- Find.WindowStack.Add(new Dialog_DebugOptionListLister(list));
- }
- }
-
- public static class WulaDebugActionsVariables
- {
- [DebugAction("Wula Fallen Empire", "Manage Event Variables", actionType = DebugActionType.Action, allowedGameStates = AllowedGameStates.PlayingOnMap)]
- private static void ManageEventVariables()
- {
- Find.WindowStack.Add(new Dialog_ManageEventVariables());
- }
- }
-}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/EventSystem/DelayedActionManager.cs b/Source/ArachnaeSwarm/EventSystem/DelayedActionManager.cs
deleted file mode 100644
index 588ad8c..0000000
--- a/Source/ArachnaeSwarm/EventSystem/DelayedActionManager.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-using System;
-using System.Collections.Generic;
-using RimWorld;
-using RimWorld.Planet;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public class DelayedActionManager : WorldComponent
- {
- // Nested class must be public to be accessible for serialization
- public class DelayedAction : IExposable
- {
- public int TicksRemaining;
- public string eventDefName;
-
- // Parameterless constructor for Scribe
- public DelayedAction() { }
-
- public DelayedAction(string eventDefName, int ticks)
- {
- this.eventDefName = eventDefName;
- this.TicksRemaining = ticks;
- }
-
- public void ExposeData()
- {
- Scribe_Values.Look(ref TicksRemaining, "ticksRemaining", 0);
- Scribe_Values.Look(ref eventDefName, "eventDefName");
- }
- }
-
- private List actions = new List();
-
- public DelayedActionManager(World world) : base(world)
- {
- }
-
- public void AddAction(string eventDefName, int delayTicks)
- {
- if (string.IsNullOrEmpty(eventDefName) || delayTicks <= 0)
- {
- return;
- }
- actions.Add(new DelayedAction(eventDefName, delayTicks));
- }
-
- public override void WorldComponentTick()
- {
- base.WorldComponentTick();
- for (int i = actions.Count - 1; i >= 0; i--)
- {
- DelayedAction delayedAction = actions[i];
- delayedAction.TicksRemaining--;
- if (delayedAction.TicksRemaining <= 0)
- {
- try
- {
- ExecuteAction(delayedAction.eventDefName);
- }
- catch (Exception ex)
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Error executing delayed action for event '{delayedAction.eventDefName}': {ex}");
- }
- actions.RemoveAt(i);
- }
- }
- }
-
- private void ExecuteAction(string defName)
- {
- EventDef nextDef = DefDatabase.GetNamed(defName, false);
- if (nextDef != null)
- {
- // This logic is simplified from Effect_OpenCustomUI.OpenUI
- // It assumes delayed actions always open a new dialog.
- Find.WindowStack.Add((Window)Activator.CreateInstance(nextDef.windowType, nextDef));
- }
- else
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] DelayedActionManager could not find EventDef named '{defName}'");
- }
- }
-
- public override void ExposeData()
- {
- base.ExposeData();
- Scribe_Collections.Look(ref actions, "delayedActions", LookMode.Deep);
- if (actions == null)
- {
- actions = new List();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/EventSystem/Dialog_CustomDisplay.cs b/Source/ArachnaeSwarm/EventSystem/Dialog_CustomDisplay.cs
deleted file mode 100644
index e9045d5..0000000
--- a/Source/ArachnaeSwarm/EventSystem/Dialog_CustomDisplay.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.RegularExpressions;
-using UnityEngine;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public class Dialog_CustomDisplay : Window
- {
- private EventDef def;
- private Texture2D portrait;
- private Texture2D background;
- private string selectedDescription;
-
- private static EventUIConfigDef config;
- public static EventUIConfigDef Config
- {
- get
- {
- if (config == null)
- {
- config = DefDatabase.GetNamed("ARA_EventUIConfig");
- }
- return config;
- }
- }
-
- public override Vector2 InitialSize
- {
- get
- {
- if (def.windowSize != Vector2.zero)
- {
- return def.windowSize;
- }
- return Config.defaultWindowSize;
- }
- }
-
- public Dialog_CustomDisplay(EventDef def)
- {
- this.def = def;
- this.forcePause = true;
- this.absorbInputAroundWindow = true;
- this.doCloseX = true;
-
- var eventVarManager = Find.World.GetComponent();
- if (!def.descriptions.NullOrEmpty())
- {
- if (def.descriptionMode == DescriptionSelectionMode.Random)
- {
- selectedDescription = def.descriptions.RandomElement();
- }
- else
- {
- string indexVarName = $"_seq_desc_index_{def.defName}";
- int currentIndex = eventVarManager.GetVariable(indexVarName, 0);
-
- selectedDescription = def.descriptions[currentIndex];
-
- int nextIndex = (currentIndex + 1) % def.descriptions.Count;
- eventVarManager.SetVariable(indexVarName, nextIndex);
- }
- }
- else
- {
- selectedDescription = "Error: No descriptions found in def.";
- }
- }
-
- public override void PreOpen()
- {
- base.PreOpen();
- if (!def.portraitPath.NullOrEmpty())
- {
- portrait = ContentFinder.Get(def.portraitPath);
- }
-
- string bgPath = !def.backgroundImagePath.NullOrEmpty() ? def.backgroundImagePath : Config.defaultBackgroundImagePath;
- if (!bgPath.NullOrEmpty())
- {
- background = ContentFinder.Get(bgPath);
- }
-
- HandleAction(def.immediateEffects);
-
- if (!def.conditionalDescriptions.NullOrEmpty())
- {
- foreach (var condDesc in def.conditionalDescriptions)
- {
- string reason;
- if (AreConditionsMet(condDesc.conditions, out reason))
- {
- selectedDescription += "\n\n" + condDesc.text;
- }
- }
- }
-
- selectedDescription = FormatDescription(selectedDescription);
- }
-
- public override void DoWindowContents(Rect inRect)
- {
- if (background != null)
- {
- GUI.DrawTexture(inRect, background, ScaleMode.ScaleToFit);
- }
-
- if (Config.showDefName)
- {
- Text.Font = GameFont.Tiny;
- GUI.color = Color.gray;
- Widgets.Label(new Rect(5, 5, inRect.width - 10, 20f), def.defName);
- GUI.color = Color.white;
- }
-
- if (Config.showLabel)
- {
- Text.Font = Config.labelFont;
- Widgets.Label(new Rect(5, 20f, inRect.width - 10, 30f), def.label);
- Text.Font = GameFont.Small;
- }
-
- float virtualWidth = Config.lihuiSize.x + Config.textSize.x;
- float virtualHeight = Config.lihuiSize.y;
-
- float scaleX = inRect.width / virtualWidth;
- float scaleY = inRect.height / virtualHeight;
- float scale = Mathf.Min(scaleX, scaleY) * 0.95f;
-
- float scaledLihuiWidth = Config.lihuiSize.x * scale;
- float scaledLihuiHeight = Config.lihuiSize.y * scale;
- float scaledNameWidth = Config.nameSize.x * scale;
- float scaledNameHeight = Config.nameSize.y * scale;
- float scaledTextWidth = Config.textSize.x * scale;
- float scaledTextHeight = Config.textSize.y * scale;
- float scaledOptionsWidth = Config.optionsWidth * scale;
-
- float totalContentWidth = scaledLihuiWidth + scaledTextWidth;
- float totalContentHeight = scaledLihuiHeight;
- float startX = (inRect.width - totalContentWidth) / 2;
- float startY = (inRect.height - totalContentHeight) / 2;
-
- Rect lihuiRect = new Rect(startX, startY, scaledLihuiWidth, scaledLihuiHeight);
- if (portrait != null)
- {
- GUI.DrawTexture(lihuiRect, portrait, ScaleMode.ScaleToFit);
- }
- if (Config.drawBorders)
- {
- Widgets.DrawBox(lihuiRect);
- }
-
- Rect nameRect = new Rect(lihuiRect.xMax, lihuiRect.y, scaledNameWidth, scaledNameHeight);
- if (Config.drawBorders)
- {
- Widgets.DrawBox(nameRect);
- }
- Text.Anchor = TextAnchor.MiddleCenter;
- Text.Font = GameFont.Medium;
- Widgets.Label(nameRect, def.characterName);
- Text.Font = GameFont.Small;
- Text.Anchor = TextAnchor.UpperLeft;
-
- Rect textRect = new Rect(nameRect.x, nameRect.yMax + Config.textNameOffset * scale, scaledTextWidth, scaledTextHeight);
- if (Config.drawBorders)
- {
- Widgets.DrawBox(textRect);
- }
- Rect textInnerRect = textRect.ContractedBy(10f * scale);
- Widgets.Label(textInnerRect, selectedDescription);
-
- Rect optionRect = new Rect(nameRect.x, textRect.yMax + Config.optionsTextOffset * scale, scaledOptionsWidth, lihuiRect.height - nameRect.height - textRect.height - (Config.textNameOffset + Config.optionsTextOffset) * scale);
-
- Listing_Standard listing = new Listing_Standard();
- listing.Begin(optionRect.ContractedBy(10f * scale));
- if (def.options != null)
- {
- foreach (var option in def.options)
- {
- string reason;
- bool conditionsMet = AreConditionsMet(option.conditions, out reason);
-
- if (conditionsMet)
- {
- if (listing.ButtonText(option.label))
- {
- HandleAction(option.optionEffects);
- }
- }
- else
- {
- if (option.hideWhenDisabled)
- {
- continue;
- }
- Rect rect = listing.GetRect(30f);
- Widgets.ButtonText(rect, option.label, false, true, false);
- TooltipHandler.TipRegion(rect, GetDisabledReason(option, reason));
- }
- }
- }
- listing.End();
- }
-
- private void HandleAction(List conditionalEffects)
- {
- if (conditionalEffects.NullOrEmpty())
- {
- return;
- }
-
- foreach (var ce in conditionalEffects)
- {
- if (AreConditionsMet(ce.conditions, out _))
- {
- ce.Execute(this);
- }
- }
- }
-
- private bool AreConditionsMet(List conditions, out string reason)
- {
- reason = "";
- if (conditions.NullOrEmpty())
- {
- return true;
- }
-
- foreach (var condition in conditions)
- {
- if (!condition.IsMet(out string singleReason))
- {
- reason = singleReason;
- return false;
- }
- }
- return true;
- }
-
- private string GetDisabledReason(EventOption option, string reason)
- {
- if (!option.disabledReason.NullOrEmpty())
- {
- return option.disabledReason;
- }
- return reason;
- }
-
- public override void PostClose()
- {
- base.PostClose();
- HandleAction(def.dismissEffects);
- }
-
- private string FormatDescription(string description)
- {
- var eventVarManager = Find.World.GetComponent();
- // Use regex to find all placeholders like {variableName}
- return Regex.Replace(description, @"\{(.+?)\}", match =>
- {
- string varName = match.Groups[1].Value;
- if (eventVarManager.HasVariable(varName))
- {
- // Important: GetVariable to get any type
- return eventVarManager.GetVariable(varName)?.ToString() ?? "";
- }
- return match.Value; // Keep placeholder if variable not found
- });
- }
- }
-}
diff --git a/Source/ArachnaeSwarm/EventSystem/Dialog_ManageEventVariables.cs b/Source/ArachnaeSwarm/EventSystem/Dialog_ManageEventVariables.cs
deleted file mode 100644
index 3998c3d..0000000
--- a/Source/ArachnaeSwarm/EventSystem/Dialog_ManageEventVariables.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using UnityEngine;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public class Dialog_ManageEventVariables : Window
- {
- private Vector2 scrollPosition;
- private Dictionary editBuffers = new Dictionary();
- private EventVariableManager manager;
-
- public override Vector2 InitialSize => new Vector2(800f, 600f);
-
- public Dialog_ManageEventVariables()
- {
- forcePause = true;
- doCloseX = true;
- doCloseButton = true;
- closeOnClickedOutside = true;
- absorbInputAroundWindow = true;
- manager = Find.World.GetComponent();
- RefreshBuffers();
- }
-
- private void RefreshBuffers()
- {
- editBuffers.Clear();
- foreach (var kvp in manager.GetAllVariables())
- {
- editBuffers[kvp.Key] = kvp.Value?.ToString() ?? "";
- }
- }
-
- public override void DoWindowContents(Rect inRect)
- {
- Listing_Standard listing = new Listing_Standard();
- listing.Begin(inRect);
-
- if (listing.ButtonText("Refresh"))
- {
- RefreshBuffers();
- }
- if (listing.ButtonText("Clear All Variables"))
- {
- manager.ClearAll();
- RefreshBuffers();
- }
-
- listing.GapLine();
-
- Rect viewRect = new Rect(0f, 0f, inRect.width - 16f, manager.GetAllVariables().Count * 32f);
- Widgets.BeginScrollView(listing.GetRect(inRect.height - 100f), ref scrollPosition, viewRect);
-
- Listing_Standard varListing = new Listing_Standard();
- varListing.Begin(viewRect);
-
- var allVars = manager.GetAllVariables().OrderBy(kvp => kvp.Key).ToList();
-
- foreach (var kvp in allVars)
- {
- Rect rowRect = varListing.GetRect(30f);
- string key = kvp.Key;
- object value = kvp.Value;
- string typeName = value?.GetType().Name ?? "null";
-
- Widgets.Label(rowRect.LeftPart(0.4f).Rounded(), $"{key} ({typeName})");
-
- string buffer = editBuffers[key];
- string newValue = Widgets.TextField(rowRect.RightPart(0.6f).LeftPart(0.8f).Rounded(), buffer);
- editBuffers[key] = newValue;
-
- if (Widgets.ButtonText(rowRect.RightPart(0.1f).Rounded(), "Set"))
- {
- // Attempt to parse and set the variable
- if (value is int)
- {
- if (int.TryParse(newValue, out int intVal)) manager.SetVariable(key, intVal);
- }
- else if (value is float)
- {
- if (float.TryParse(newValue, out float floatVal)) manager.SetVariable(key, floatVal);
- }
- else
- {
- manager.SetVariable(key, newValue);
- }
- }
- }
-
- varListing.End();
- Widgets.EndScrollView();
- listing.End();
- }
- }
-}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/EventSystem/Dialog_NewLayoutDisplay.cs b/Source/ArachnaeSwarm/EventSystem/Dialog_NewLayoutDisplay.cs
deleted file mode 100644
index b0e9644..0000000
--- a/Source/ArachnaeSwarm/EventSystem/Dialog_NewLayoutDisplay.cs
+++ /dev/null
@@ -1,277 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.RegularExpressions;
-using UnityEngine;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public class Dialog_NewLayoutDisplay : Window
- {
- private EventDef def;
- private Texture2D portrait;
- private Texture2D background;
- private string selectedDescription;
-
- private static EventUIConfigDef config;
- public static EventUIConfigDef Config
- {
- get
- {
- if (config == null)
- {
- config = DefDatabase.GetNamed("ARA_EventUIConfig");
- }
- return config;
- }
- }
-
- public override Vector2 InitialSize
- {
- get
- {
- if (def.windowSize != Vector2.zero)
- {
- return def.windowSize;
- }
- return Config.defaultWindowSize;
- }
- }
-
- public Dialog_NewLayoutDisplay(EventDef def)
- {
- this.def = def;
- this.forcePause = true;
- this.absorbInputAroundWindow = true;
- this.doCloseX = true;
-
- var eventVarManager = Find.World.GetComponent();
- if (!def.descriptions.NullOrEmpty())
- {
- if (def.descriptionMode == DescriptionSelectionMode.Random)
- {
- selectedDescription = def.descriptions.RandomElement();
- }
- else
- {
- string indexVarName = $"_seq_desc_index_{def.defName}";
- int currentIndex = eventVarManager.GetVariable(indexVarName, 0);
-
- selectedDescription = def.descriptions[currentIndex];
-
- int nextIndex = (currentIndex + 1) % def.descriptions.Count;
- eventVarManager.SetVariable(indexVarName, nextIndex);
- }
- }
- else
- {
- selectedDescription = "Error: No descriptions found in def.";
- }
- }
-
- public override void PreOpen()
- {
- base.PreOpen();
- if (!def.portraitPath.NullOrEmpty())
- {
- portrait = ContentFinder.Get(def.portraitPath);
- }
-
- string bgPath = !def.backgroundImagePath.NullOrEmpty() ? def.backgroundImagePath : Config.defaultBackgroundImagePath;
- if (!bgPath.NullOrEmpty())
- {
- background = ContentFinder.Get(bgPath);
- }
-
- HandleAction(def.immediateEffects);
-
- if (!def.conditionalDescriptions.NullOrEmpty())
- {
- foreach (var condDesc in def.conditionalDescriptions)
- {
- string reason;
- if (AreConditionsMet(condDesc.conditions, out reason))
- {
- selectedDescription += "\n\n" + condDesc.text;
- }
- }
- }
-
- selectedDescription = FormatDescription(selectedDescription);
- }
-
- public override void DoWindowContents(Rect inRect)
- {
- if (background != null)
- {
- GUI.DrawTexture(inRect, background, ScaleMode.ScaleToFit);
- }
-
- if (Config.showDefName)
- {
- Text.Font = GameFont.Tiny;
- GUI.color = Color.gray;
- Widgets.Label(new Rect(5, 5, inRect.width - 10, 20f), def.defName);
- GUI.color = Color.white;
- }
-
- if (Config.showLabel)
- {
- Text.Font = Config.labelFont;
- Widgets.Label(new Rect(5, 20f, inRect.width - 10, 30f), def.label);
- Text.Font = GameFont.Small;
- }
-
- // 假设一个统一的边距
- float padding = Config.newLayoutPadding;
-
- // 名称区域
- float nameHeight = Config.newLayoutNameSize.y;
- float nameWidth = Config.newLayoutNameSize.x;
- Rect nameRect = new Rect(inRect.x + (inRect.width - nameWidth) / 2f, inRect.y + padding, nameWidth, nameHeight);
- if (Config.drawBorders)
- {
- Widgets.DrawBox(nameRect);
- }
- Text.Anchor = TextAnchor.MiddleCenter;
- Text.Font = GameFont.Medium;
- Widgets.Label(nameRect, def.characterName);
- Text.Font = GameFont.Small;
- Text.Anchor = TextAnchor.UpperLeft;
-
- // 立绘区域
- float lihuiWidth = Config.newLayoutLihuiSize.x;
- float lihuiHeight = Config.newLayoutLihuiSize.y;
- Rect lihuiRect = new Rect(inRect.x + (inRect.width - lihuiWidth) / 2f, nameRect.yMax + padding, lihuiWidth, lihuiHeight);
- if (portrait != null)
- {
- GUI.DrawTexture(lihuiRect, portrait, ScaleMode.ScaleToFit);
- }
- if (Config.drawBorders)
- {
- Widgets.DrawBox(lihuiRect);
- }
-
- // 选项区域 (预先计算高度)
- float optionButtonHeight = 30f; // 每个按钮的高度
- float optionSpacing = 5f; // 按钮之间的间距
- float calculatedOptionHeight = 0f;
- if (def.options != null && def.options.Any())
- {
- calculatedOptionHeight = def.options.Count * optionButtonHeight + (def.options.Count - 1) * optionSpacing;
- }
- calculatedOptionHeight = Mathf.Max(calculatedOptionHeight, 100f); // 最小高度
-
- float optionsWidth = Config.newLayoutOptionsWidth;
- Rect optionRect = new Rect(inRect.x + (inRect.width - optionsWidth) / 2f, inRect.yMax - padding - calculatedOptionHeight, optionsWidth, calculatedOptionHeight);
-
- // 描述区域
- float textWidth = Config.newLayoutTextSize.x;
- Rect textRect = new Rect(inRect.x + (inRect.width - textWidth) / 2f, lihuiRect.yMax + padding, textWidth, optionRect.y - (lihuiRect.yMax + padding) - padding);
- if (Config.drawBorders)
- {
- Widgets.DrawBox(textRect);
- }
- Rect textInnerRect = textRect.ContractedBy(padding);
- Widgets.Label(textInnerRect, selectedDescription);
-
- // 选项列表的绘制
- Listing_Standard listing = new Listing_Standard();
- listing.Begin(optionRect); // 使用完整的 optionRect
- if (def.options != null)
- {
- foreach (var option in def.options)
- {
- string reason;
- bool conditionsMet = AreConditionsMet(option.conditions, out reason);
-
- if (conditionsMet)
- {
- if (listing.ButtonText(option.label))
- {
- HandleAction(option.optionEffects);
- }
- }
- else
- {
- if (option.hideWhenDisabled)
- {
- continue;
- }
- Rect rect = listing.GetRect(30f);
- Widgets.ButtonText(rect, option.label, false, true, false);
- TooltipHandler.TipRegion(rect, GetDisabledReason(option, reason));
- }
- }
- }
- listing.End();
- }
-
- private void HandleAction(List conditionalEffects)
- {
- if (conditionalEffects.NullOrEmpty())
- {
- return;
- }
-
- foreach (var ce in conditionalEffects)
- {
- if (AreConditionsMet(ce.conditions, out _))
- {
- ce.Execute(this);
- }
- }
- }
-
- private bool AreConditionsMet(List conditions, out string reason)
- {
- reason = "";
- if (conditions.NullOrEmpty())
- {
- return true;
- }
-
- foreach (var condition in conditions)
- {
- if (!condition.IsMet(out string singleReason))
- {
- reason = singleReason;
- return false;
- }
- }
- return true;
- }
-
- private string GetDisabledReason(EventOption option, string reason)
- {
- if (!option.disabledReason.NullOrEmpty())
- {
- return option.disabledReason;
- }
- return reason;
- }
-
- public override void PostClose()
- {
- base.PostClose();
- HandleAction(def.dismissEffects);
- }
-
- private string FormatDescription(string description)
- {
- var eventVarManager = Find.World.GetComponent();
- // Use regex to find all placeholders like {variableName}
- return Regex.Replace(description, @"\{(.+?)\}", match =>
- {
- string varName = match.Groups[1].Value;
- if (eventVarManager.HasVariable(varName))
- {
- // Important: GetVariable to get any type
- return eventVarManager.GetVariable(varName)?.ToString() ?? "";
- }
- return match.Value; // Keep placeholder if variable not found
- });
- }
- }
-}
diff --git a/Source/ArachnaeSwarm/EventSystem/Effect.cs b/Source/ArachnaeSwarm/EventSystem/Effect.cs
deleted file mode 100644
index 9647cb2..0000000
--- a/Source/ArachnaeSwarm/EventSystem/Effect.cs
+++ /dev/null
@@ -1,655 +0,0 @@
-using System; // Required for Activator
-using System.Collections.Generic;
-using System.Linq;
-using UnityEngine;
-using Verse;
-using RimWorld;
-
-namespace ArachnaeSwarm
-{
- public abstract class Effect
- {
- public float weight = 1.0f;
- public abstract void Execute(Window dialog = null);
- }
-
- public class Effect_OpenCustomUI : Effect
- {
- public string defName;
- public int delayTicks = 0;
-
- public override void Execute(Window dialog = null)
- {
- if (delayTicks > 0)
- {
- var actionManager = Find.World.GetComponent();
- if (actionManager != null)
- {
- actionManager.AddAction(defName, delayTicks);
- }
- else
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] DelayedActionManager not found. Cannot schedule delayed UI opening.");
- }
- }
- else
- {
- OpenUI();
- }
- }
-
- private void OpenUI()
- {
- EventDef nextDef = DefDatabase.GetNamed(defName);
- if (nextDef != null)
- {
- if (nextDef.hiddenWindow)
- {
- if (!nextDef.dismissEffects.NullOrEmpty())
- {
- foreach (var conditionalEffect in nextDef.dismissEffects)
- {
- string reason;
- if (AreConditionsMet(conditionalEffect.conditions, out reason))
- {
- conditionalEffect.Execute(null);
- }
- }
- }
- }
- else
- {
- Find.WindowStack.Add((Window)Activator.CreateInstance(nextDef.windowType, nextDef));
- }
- }
- else
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Effect_OpenCustomUI could not find EventDef named '{defName}'");
- }
- }
-
- private bool AreConditionsMet(List conditions, out string reason)
- {
- reason = "";
- if (conditions.NullOrEmpty())
- {
- return true;
- }
-
- foreach (var condition in conditions)
- {
- if (!condition.IsMet(out string singleReason))
- {
- reason = singleReason;
- return false;
- }
- }
- return true;
- }
- }
-
- public class Effect_CloseDialog : Effect
- {
- public override void Execute(Window dialog = null)
- {
- dialog?.Close();
- }
- }
-
- public class Effect_ShowMessage : Effect
- {
- public string message;
- public MessageTypeDef messageTypeDef;
-
- public override void Execute(Window dialog = null)
- {
- if (messageTypeDef == null)
- {
- messageTypeDef = MessageTypeDefOf.PositiveEvent;
- }
- Messages.Message(message, messageTypeDef);
- }
- }
-
- public class Effect_FireIncident : Effect
- {
- public IncidentDef incident;
-
- public override void Execute(Window dialog = null)
- {
- if (incident == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_FireIncident has a null incident Def.");
- return;
- }
-
- IncidentParms parms = new IncidentParms
- {
- target = Find.CurrentMap,
- forced = true
- };
-
- if (!incident.Worker.TryExecute(parms))
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Could not fire incident {incident.defName}");
- }
- }
- }
-
- public class Effect_ChangeFactionRelation : Effect
- {
- public FactionDef faction;
- public int goodwillChange;
-
- public override void Execute(Window dialog = null)
- {
- if (faction == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_ChangeFactionRelation has a null faction Def.");
- return;
- }
-
- Faction targetFaction = Find.FactionManager.FirstFactionOfDef(faction);
- if (targetFaction == null)
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Could not find an active faction for FactionDef '{faction.defName}'.");
- return;
- }
-
- Faction.OfPlayer.TryAffectGoodwillWith(targetFaction, goodwillChange, canSendMessage: true, canSendHostilityLetter: true, reason: null, lookTarget: null);
- }
- }
-
- public class Effect_SetVariable : Effect
- {
- public string name;
- public string value;
- public string type; // Int, Float, String, Bool
- public bool forceSet = false;
-
- public override void Execute(Window dialog = null)
- {
- var eventVarManager = Find.World.GetComponent();
- if (!forceSet && eventVarManager.HasVariable(name))
- {
- return;
- }
-
- object realValue = value;
- if (!string.IsNullOrEmpty(type))
- {
- if (type.Equals("int", System.StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out int intVal))
- {
- realValue = intVal;
- }
- else if (type.Equals("float", System.StringComparison.OrdinalIgnoreCase) && float.TryParse(value, out float floatVal))
- {
- realValue = floatVal;
- }
- else if (type.Equals("bool", System.StringComparison.OrdinalIgnoreCase) && bool.TryParse(value, out bool boolVal))
- {
- realValue = boolVal;
- }
- }
- eventVarManager.SetVariable(name, realValue);
- }
- }
-
- public class Effect_ChangeFactionRelation_FromVariable : Effect
- {
- public FactionDef faction;
- public string goodwillVariableName;
-
- public override void Execute(Window dialog = null)
- {
- if (faction == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_ChangeFactionRelation_FromVariable has a null faction Def.");
- return;
- }
-
- Faction targetFaction = Find.FactionManager.FirstFactionOfDef(faction);
- if (targetFaction == null)
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Could not find an active faction for FactionDef '{faction.defName}'.");
- return;
- }
-
- int goodwillChange = Find.World.GetComponent().GetVariable(goodwillVariableName);
- Faction.OfPlayer.TryAffectGoodwillWith(targetFaction, goodwillChange, canSendMessage: true, canSendHostilityLetter: true, reason: null, lookTarget: null);
- }
- }
-
- public class Effect_SpawnPawnAndStore : Effect
- {
- public PawnKindDef kindDef;
- public int count = 1;
- public string storeAs;
-
- public override void Execute(Window dialog = null)
- {
- if (kindDef == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_SpawnPawnAndStore has a null kindDef.");
- return;
- }
- if (storeAs.NullOrEmpty())
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_SpawnPawnAndStore needs a 'storeAs' variable name.");
- return;
- }
-
- var eventVarManager = Find.World.GetComponent();
- List spawnedPawns = new List();
- for (int i = 0; i < count; i++)
- {
- Pawn newPawn = PawnGenerator.GeneratePawn(kindDef, Faction.OfPlayer);
- IntVec3 loc = CellFinder.RandomSpawnCellForPawnNear(Find.CurrentMap.mapPawns.FreeColonists.First().Position, Find.CurrentMap, 10);
- GenSpawn.Spawn(newPawn, loc, Find.CurrentMap);
- spawnedPawns.Add(newPawn);
- }
-
- if (count == 1)
- {
- eventVarManager.SetVariable(storeAs, spawnedPawns.First());
- }
- else
- {
- eventVarManager.SetVariable(storeAs, spawnedPawns);
- }
- }
- }
-
- public class Effect_GiveThing : Effect
- {
- public ThingDef thingDef;
- public int count = 1;
-
- public override void Execute(Window dialog = null)
- {
- if (thingDef == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_GiveThing has a null thingDef.");
- return;
- }
-
- Map currentMap = Find.CurrentMap;
- if (currentMap == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_GiveThing cannot execute without a current map.");
- return;
- }
-
- Thing thing = ThingMaker.MakeThing(thingDef);
- thing.stackCount = count;
-
- IntVec3 dropCenter = DropCellFinder.TradeDropSpot(currentMap);
- DropPodUtility.DropThingsNear(dropCenter, currentMap, new List { thing }, 110, false, false, false, false);
-
- Messages.Message("LetterLabelCargoPodCrash".Translate(), new TargetInfo(dropCenter, currentMap), MessageTypeDefOf.PositiveEvent);
- }
- }
-
- public class Effect_SpawnPawn : Effect
- {
- public PawnKindDef kindDef;
- public int count = 1;
- public bool joinPlayerFaction = true;
- public string letterLabel;
- public string letterText;
- public LetterDef letterDef;
-
- public override void Execute(Window dialog = null)
- {
- if (kindDef == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_SpawnPawn has a null kindDef.");
- return;
- }
-
- Map map = Find.CurrentMap;
- if (map == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_SpawnPawn cannot execute without a current map.");
- return;
- }
-
- for (int i = 0; i < count; i++)
- {
- Faction faction = joinPlayerFaction ? Faction.OfPlayer : null;
- PawnGenerationRequest request = new PawnGenerationRequest(
- kindDef, faction, PawnGenerationContext.NonPlayer, -1, true, false, false, false,
- true, 20f, false, true, false, true, true, false, false, false, false, 0f, 0f, null, 1f,
- null, null, null, null, null, null, null, null, null, null, null, null, false
- );
- Pawn pawn = PawnGenerator.GeneratePawn(request);
-
- if (!CellFinder.TryFindRandomEdgeCellWith((IntVec3 c) => map.reachability.CanReachColony(c) && !c.Fogged(map), map, CellFinder.EdgeRoadChance_Neutral, out IntVec3 cell))
- {
- cell = DropCellFinder.RandomDropSpot(map);
- }
-
- GenSpawn.Spawn(pawn, cell, map, WipeMode.Vanish);
-
- if (!string.IsNullOrEmpty(letterLabel) && !string.IsNullOrEmpty(letterText))
- {
- TaggedString finalLabel = letterLabel.Formatted(pawn.Named("PAWN")).AdjustedFor(pawn);
- TaggedString finalText = letterText.Formatted(pawn.Named("PAWN")).AdjustedFor(pawn);
- PawnRelationUtility.TryAppendRelationsWithColonistsInfo(ref finalText, ref finalLabel, pawn);
- Find.LetterStack.ReceiveLetter(finalLabel, finalText, letterDef ?? LetterDefOf.PositiveEvent, pawn);
- }
- }
- }
- }
-
- public enum VariableOperation
- {
- Add,
- Subtract,
- Multiply,
- Divide
- }
-
- public class Effect_ModifyVariable : Effect
- {
- public string name;
- public string value;
- public string valueVariableName;
- public VariableOperation operation;
-
- public override void Execute(Window dialog = null)
- {
- if (string.IsNullOrEmpty(name))
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_ModifyVariable has a null or empty name.");
- return;
- }
-
- var eventVarManager = Find.World.GetComponent();
-
- // Determine the value to modify by
- string valueStr = value;
- if (!string.IsNullOrEmpty(valueVariableName))
- {
- valueStr = eventVarManager.GetVariable(valueVariableName)?.ToString();
- if (valueStr == null)
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Effect_ModifyVariable: valueVariableName '{valueVariableName}' not found.");
- return;
- }
- }
-
- // Get the target variable, or initialize it
- object variable = eventVarManager.GetVariable(name);
- if (variable == null)
- {
- ArachnaeLog.Debug($"[EventSystem] Effect_ModifyVariable: Variable '{name}' not found, initializing to 0.");
- variable = 0;
- }
-
- object originalValue = variable;
- object newValue = null;
-
- // Perform operation based on type
- try
- {
- if (variable is int || (variable is float && !valueStr.Contains("."))) // Allow int ops
- {
- int currentVal = System.Convert.ToInt32(variable);
- int modVal = int.Parse(valueStr);
- newValue = (int)Modify((float)currentVal, (float)modVal, operation);
- }
- else // Default to float operation
- {
- float currentVal = System.Convert.ToSingle(variable);
- float modVal = float.Parse(valueStr);
- newValue = Modify(currentVal, modVal, operation);
- }
-
- ArachnaeLog.Debug($"[EventSystem] Modifying variable '{name}'. Operation: {operation}. Value: {valueStr}. From: {originalValue} To: {newValue}");
- eventVarManager.SetVariable(name, newValue);
- }
- catch (System.Exception e)
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Effect_ModifyVariable: Could not parse or operate on value '{valueStr}' for variable '{name}'. Error: {e.Message}");
- }
- }
-
- private float Modify(float current, float modifier, VariableOperation op)
- {
- switch (op)
- {
- case VariableOperation.Add: return current + modifier;
- case VariableOperation.Subtract: return current - modifier;
- case VariableOperation.Multiply: return current * modifier;
- case VariableOperation.Divide:
- if (modifier != 0) return current / modifier;
- ArachnaeLog.Debug($"[WulaFallenEmpire] Effect_ModifyVariable tried to divide by zero.");
- return current;
- default: return current;
- }
- }
- }
-
- public class Effect_ClearVariable : Effect
- {
- public string name;
-
- public override void Execute(Window dialog = null)
- {
- if (string.IsNullOrEmpty(name))
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_ClearVariable has a null or empty name.");
- return;
- }
- Find.World.GetComponent().ClearVariable(name);
- }
- }
-
- public class Effect_AddQuest : Effect
- {
- public QuestScriptDef quest;
-
- public override void Execute(Window dialog = null)
- {
- if (quest == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_AddQuest has a null quest Def.");
- return;
- }
-
- Quest newQuest = Quest.MakeRaw();
- newQuest.root = quest;
- newQuest.id = Find.UniqueIDsManager.GetNextQuestID();
- Find.QuestManager.Add(newQuest);
- }
- }
-
- public class Effect_FinishResearch : Effect
- {
- public ResearchProjectDef research;
-
- public override void Execute(Window dialog = null)
- {
- if (research == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_FinishResearch has a null research Def.");
- return;
- }
-
- Find.ResearchManager.FinishProject(research);
- }
- }
- public class Effect_TriggerRaid : Effect
- {
- public float points;
- public FactionDef faction;
- public RaidStrategyDef raidStrategy;
- public PawnsArrivalModeDef raidArrivalMode;
- public PawnGroupKindDef groupKind;
- public List pawnGroupMakers;
- public string letterLabel;
- public string letterText;
-
- public override void Execute(Window dialog = null)
- {
- Map map = Find.CurrentMap;
- if (map == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_TriggerRaid cannot execute without a current map.");
- return;
- }
-
- Faction factionInst = Find.FactionManager.FirstFactionOfDef(this.faction);
- if (factionInst == null)
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] Effect_TriggerRaid could not find an active faction for FactionDef '{this.faction?.defName}'.");
- return;
- }
-
- IncidentParms parms = new IncidentParms
- {
- target = map,
- points = this.points,
- faction = factionInst,
- raidStrategy = this.raidStrategy,
- raidArrivalMode = this.raidArrivalMode,
- pawnGroupMakerSeed = Rand.Int,
- forced = true
- };
-
- if (!RCellFinder.TryFindRandomPawnEntryCell(out parms.spawnCenter, map, CellFinder.EdgeRoadChance_Hostile))
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_TriggerRaid could not find a valid spawn center.");
- return;
- }
-
- PawnGroupMakerParms groupMakerParms = new PawnGroupMakerParms
- {
- groupKind = this.groupKind ?? PawnGroupKindDefOf.Combat,
- tile = map.Tile,
- points = this.points,
- faction = factionInst,
- raidStrategy = this.raidStrategy,
- seed = parms.pawnGroupMakerSeed
- };
-
- List pawns;
- if (!pawnGroupMakers.NullOrEmpty())
- {
- var groupMaker = pawnGroupMakers.RandomElementByWeight(x => x.commonality);
- pawns = groupMaker.GeneratePawns(groupMakerParms).ToList();
- }
- else
- {
- pawns = PawnGroupMakerUtility.GeneratePawns(groupMakerParms).ToList();
- }
-
- if (pawns.Any())
- {
- raidArrivalMode.Worker.Arrive(pawns, parms);
- // Assign Lord and LordJob to make the pawns actually perform the raid.
- raidStrategy.Worker.MakeLords(parms, pawns);
-
- if (!string.IsNullOrEmpty(letterLabel) && !string.IsNullOrEmpty(letterText))
- {
- Find.LetterStack.ReceiveLetter(letterLabel, letterText, LetterDefOf.ThreatBig, pawns[0]);
- }
- }
- }
- }
-
- public class Effect_CheckFactionGoodwill : Effect
- {
- public FactionDef factionDef;
- public string variableName;
-
- public override void Execute(Window dialog = null)
- {
- if (factionDef == null || string.IsNullOrEmpty(variableName))
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_CheckFactionGoodwill is not configured correctly.");
- return;
- }
-
- var eventVarManager = Find.World.GetComponent();
- Faction faction = Find.FactionManager.FirstFactionOfDef(factionDef);
-
- if (faction != null)
- {
- int goodwill = faction.GoodwillWith(Faction.OfPlayer);
- ArachnaeLog.Debug($"[EventSystem] Storing goodwill for faction '{faction.Name}' ({goodwill}) into variable '{variableName}'.");
- eventVarManager.SetVariable(variableName, goodwill);
- }
- else
- {
- ArachnaeLog.Debug($"[EventSystem] Effect_CheckFactionGoodwill: Faction '{factionDef.defName}' not found. Storing 0 in variable '{variableName}'.");
- eventVarManager.SetVariable(variableName, 0);
- }
- }
- }
-
- public class Effect_StoreRealPlayTime : Effect
- {
- public string variableName;
-
- public override void Execute(Window dialog = null)
- {
- if (string.IsNullOrEmpty(variableName))
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_StoreRealPlayTime is not configured correctly (missing variableName).");
- return;
- }
-
- var eventVarManager = Find.World.GetComponent();
- float realPlayTime = Find.GameInfo.RealPlayTimeInteracting;
- ArachnaeLog.Debug($"[EventSystem] Storing real play time ({realPlayTime}s) into variable '{variableName}'.");
- eventVarManager.SetVariable(variableName, realPlayTime);
- }
- }
-
- public class Effect_StoreDaysPassed : Effect
- {
- public string variableName;
-
- public override void Execute(Window dialog = null)
- {
- if (string.IsNullOrEmpty(variableName))
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_StoreDaysPassed is not configured correctly (missing variableName).");
- return;
- }
-
- var eventVarManager = Find.World.GetComponent();
- int daysPassed = GenDate.DaysPassed;
- ArachnaeLog.Debug($"[EventSystem] Storing days passed ({daysPassed}) into variable '{variableName}'.");
- eventVarManager.SetVariable(variableName, daysPassed);
- }
- }
-
- public class Effect_StoreColonyWealth : Effect
- {
- public string variableName;
-
- public override void Execute(Window dialog = null)
- {
- if (string.IsNullOrEmpty(variableName))
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_StoreColonyWealth is not configured correctly (missing variableName).");
- return;
- }
-
- Map currentMap = Find.CurrentMap;
- if (currentMap == null)
- {
- ArachnaeLog.Debug("[WulaFallenEmpire] Effect_StoreColonyWealth cannot execute without a current map.");
- return;
- }
-
- var eventVarManager = Find.World.GetComponent();
- float wealth = currentMap.wealthWatcher.WealthTotal;
- ArachnaeLog.Debug($"[EventSystem] Storing colony wealth ({wealth}) into variable '{variableName}'.");
- eventVarManager.SetVariable(variableName, wealth);
- }
- }
-}
diff --git a/Source/ArachnaeSwarm/EventSystem/EventDef.cs b/Source/ArachnaeSwarm/EventSystem/EventDef.cs
deleted file mode 100644
index 9adaac9..0000000
--- a/Source/ArachnaeSwarm/EventSystem/EventDef.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using System; // Add this line
-using System.Collections.Generic;
-using System.Linq;
-using UnityEngine;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public enum DescriptionSelectionMode
- {
- Random,
- Sequential
- }
-
- public class EventDef : Def
- {
- public string portraitPath;
- public string characterName;
-
- // New system: list of descriptions
- public List descriptions;
- public DescriptionSelectionMode descriptionMode = DescriptionSelectionMode.Random;
- public bool hiddenWindow = false;
-
- // Backwards compatibility: old single description field
- public new string description = null;
-
- public Vector2 windowSize = Vector2.zero;
-
- public Type windowType = typeof(Dialog_CustomDisplay); // 默认窗口类型
- public List options;
- public string backgroundImagePath;
- public List immediateEffects;
- public List dismissEffects;
- public List conditionalDescriptions;
-
- public override void PostLoad()
- {
- base.PostLoad();
-#pragma warning disable 0618
- // If the old description field is used, move its value to the new list for processing.
- if (!description.NullOrEmpty())
- {
- if (descriptions.NullOrEmpty())
- {
- descriptions = new List();
- }
- descriptions.Insert(0, description);
- description = null; // Clear the old field to prevent confusion
- }
-#pragma warning restore 0618
- // If hiddenWindow is true, merge immediateEffects into dismissEffects at load time.
- if (hiddenWindow && !immediateEffects.NullOrEmpty())
- {
- if (dismissEffects.NullOrEmpty())
- {
- dismissEffects = new List();
- }
- dismissEffects.AddRange(immediateEffects);
- immediateEffects = null; // Clear to prevent double execution
- }
- }
- }
-
- public class EventOption
- {
- public string label;
- public List optionEffects;
- public List conditions;
- public string disabledReason;
- public bool hideWhenDisabled = false;
- }
-
- public class LoopEffects
- {
- public int count = 1;
- public string countVariableName;
- public List effects;
- }
-
- public class ConditionalEffects
- {
- public List conditions;
- public List effects;
- public List randomlistEffects;
- public List loopEffects;
-
- public void Execute(Window dialog)
- {
- // Execute all standard effects
- if (!effects.NullOrEmpty())
- {
- foreach (var effect in effects)
- {
- effect.Execute(dialog);
- }
- }
-
- // Execute one random effect from the random list
- if (!randomlistEffects.NullOrEmpty())
- {
- float totalWeight = randomlistEffects.Sum(e => e.weight);
- float randomPoint = Rand.Value * totalWeight;
-
- foreach (var effect in randomlistEffects)
- {
- if (randomPoint < effect.weight)
- {
- effect.Execute(dialog);
- break;
- }
- randomPoint -= effect.weight;
- }
- }
-
- // Execute looped effects
- if (!loopEffects.NullOrEmpty())
- {
- var eventVarManager = Find.World.GetComponent();
- foreach (var loop in loopEffects)
- {
- int loopCount = loop.count;
- if (!loop.countVariableName.NullOrEmpty() && eventVarManager.HasVariable(loop.countVariableName))
- {
- loopCount = eventVarManager.GetVariable(loop.countVariableName);
- }
-
- for (int i = 0; i < loopCount; i++)
- {
- if (!loop.effects.NullOrEmpty())
- {
- foreach (var effect in loop.effects)
- {
- effect.Execute(dialog);
- }
- }
- }
- }
- }
- }
- }
-
- public class ConditionalDescription
- {
- public List conditions;
- public string text;
- }
-}
diff --git a/Source/ArachnaeSwarm/EventSystem/EventUIConfigDef.cs b/Source/ArachnaeSwarm/EventSystem/EventUIConfigDef.cs
deleted file mode 100644
index 6c4dd91..0000000
--- a/Source/ArachnaeSwarm/EventSystem/EventUIConfigDef.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using UnityEngine;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public class EventUIConfigDef : Def
- {
- // General Style
- public GameFont labelFont = GameFont.Small;
- public bool drawBorders = true;
- public bool showDefName = true;
- public bool showLabel = true;
- public string defaultBackgroundImagePath;
- public Vector2 defaultWindowSize = new Vector2(750f, 500f);
-
- // Virtual Layout Dimensions
- public Vector2 lihuiSize = new Vector2(500f, 800f);
- public Vector2 nameSize = new Vector2(260f, 130f);
- public Vector2 textSize = new Vector2(650f, 500f);
- public float optionsWidth = 610f;
-
- // Virtual Layout Offsets
- public float textNameOffset = 20f;
- public float optionsTextOffset = 20f;
- // New Layout Dimensions
- public Vector2 newLayoutNameSize = new Vector2(200f, 50f);
- public Vector2 newLayoutLihuiSize = new Vector2(300f, 400f);
- public Vector2 newLayoutTextSize = new Vector2(600f, 200f);
- public float newLayoutOptionsWidth = 600f;
- public float newLayoutPadding = 20f;
- public float newLayoutTextNameOffset = 20f;
- public float newLayoutOptionsTextOffset = 20f;
- }
-}
diff --git a/Source/ArachnaeSwarm/EventSystem/EventVariableManager.cs b/Source/ArachnaeSwarm/EventSystem/EventVariableManager.cs
deleted file mode 100644
index b6073f1..0000000
--- a/Source/ArachnaeSwarm/EventSystem/EventVariableManager.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-using System.Collections.Generic;
-using Verse;
-using RimWorld;
-using RimWorld.Planet;
-
-namespace ArachnaeSwarm
-{
- public class EventVariableManager : WorldComponent
- {
- private Dictionary intVars = new Dictionary();
- private Dictionary floatVars = new Dictionary();
- private Dictionary stringVars = new Dictionary();
- private Dictionary pawnVars = new Dictionary();
- private Dictionary> pawnListVars = new Dictionary>();
-
- // 用于Scribe的辅助列表
- private List pawnVarKeys;
- private List pawnVarValues;
- private List pawnListVarKeys;
- private List> pawnListVarValues;
-
- // Required for WorldComponent
- public EventVariableManager(World world) : base(world)
- {
- }
-
- public override void ExposeData()
- {
- base.ExposeData();
- Scribe_Collections.Look(ref intVars, "intVars", LookMode.Value, LookMode.Value);
- Scribe_Collections.Look(ref floatVars, "floatVars", LookMode.Value, LookMode.Value);
- Scribe_Collections.Look(ref stringVars, "stringVars", LookMode.Value, LookMode.Value);
- Scribe_Collections.Look(ref pawnVars, "pawnVars", LookMode.Value, LookMode.Reference, ref pawnVarKeys, ref pawnVarValues);
- Scribe_Collections.Look(ref pawnListVars, "pawnListVars", LookMode.Value, LookMode.Reference, ref pawnListVarKeys, ref pawnListVarValues);
-
- // Ensure dictionaries are not null after loading
- if (Scribe.mode == LoadSaveMode.PostLoadInit)
- {
- intVars ??= new Dictionary();
- floatVars ??= new Dictionary();
- stringVars ??= new Dictionary();
- pawnVars ??= new Dictionary();
- pawnListVars ??= new Dictionary>();
- }
- }
-
- public void SetVariable(string name, object value)
- {
- if (string.IsNullOrEmpty(name)) return;
-
- // Log the variable change
- ArachnaeLog.Debug($"[EventSystem] Setting variable '{name}' to value '{value}' of type {value?.GetType().Name ?? "null"}.");
-
- // Clear any existing variable with the same name to prevent type confusion
- ClearVariable(name);
-
- if (value is int intValue)
- {
- intVars[name] = intValue;
- }
- else if (value is float floatValue)
- {
- floatVars[name] = floatValue;
- }
- else if (value is string stringValue)
- {
- stringVars[name] = stringValue;
- }
- else if (value is Pawn pawnValue)
- {
- pawnVars[name] = pawnValue;
- }
- else if (value is List pawnListValue)
- {
- pawnListVars[name] = pawnListValue;
- }
- else if (value != null)
- {
- stringVars[name] = value.ToString();
- ArachnaeLog.Debug($"[WulaFallenEmpire] EventVariableManager: Variable '{name}' of type {value.GetType()} was converted to string for storage. This may lead to unexpected behavior.");
- }
- }
-
- public T GetVariable(string name, T defaultValue = default)
- {
- if (string.IsNullOrEmpty(name)) return defaultValue;
-
- object value = null;
- if (pawnListVars.TryGetValue(name, out var pawnListVal))
- {
- value = pawnListVal;
- }
- else if (pawnVars.TryGetValue(name, out var pawnVal))
- {
- value = pawnVal;
- }
- else if (floatVars.TryGetValue(name, out var floatVal))
- {
- value = floatVal;
- }
- else if (intVars.TryGetValue(name, out var intVal))
- {
- value = intVal;
- }
- else if (stringVars.TryGetValue(name, out var stringVal))
- {
- value = stringVal;
- }
-
- if (value != null)
- {
- if (value is T typedValue)
- {
- return typedValue;
- }
- try
- {
- // Handle cases where T is object but the stored value is, e.g., an int
- if (typeof(T) == typeof(object))
- {
- return (T)value;
- }
- return (T)System.Convert.ChangeType(value, typeof(T));
- }
- catch (System.Exception e)
- {
- ArachnaeLog.Debug($"[WulaFallenEmpire] EventVariableManager: Variable '{name}' of type {value.GetType()} could not be converted to {typeof(T)}. Error: {e.Message}");
- return defaultValue;
- }
- }
-
- return defaultValue;
- }
-
- public bool HasVariable(string name)
- {
- return intVars.ContainsKey(name) ||
- floatVars.ContainsKey(name) ||
- stringVars.ContainsKey(name) ||
- pawnVars.ContainsKey(name) ||
- pawnListVars.ContainsKey(name);
- }
-
- public void ClearVariable(string name)
- {
- if (HasVariable(name))
- {
- ArachnaeLog.Debug($"[EventSystem] Clearing variable '{name}'.");
- }
- intVars.Remove(name);
- floatVars.Remove(name);
- stringVars.Remove(name);
- pawnVars.Remove(name);
- pawnListVars.Remove(name);
- }
-
- public void ClearAll()
- {
- intVars.Clear();
- floatVars.Clear();
- stringVars.Clear();
- pawnVars.Clear();
- pawnListVars.Clear();
- }
-
- public Dictionary GetAllVariables()
- {
- var allVars = new Dictionary();
- foreach (var kvp in intVars) allVars[kvp.Key] = kvp.Value;
- foreach (var kvp in floatVars) allVars[kvp.Key] = kvp.Value;
- foreach (var kvp in stringVars) allVars[kvp.Key] = kvp.Value;
- foreach (var kvp in pawnVars) allVars[kvp.Key] = kvp.Value;
- foreach (var kvp in pawnListVars) allVars[kvp.Key] = kvp.Value;
- return allVars;
- }
- }
-}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/EventSystem/Letter_EventChoice.cs b/Source/ArachnaeSwarm/EventSystem/Letter_EventChoice.cs
deleted file mode 100644
index cdc99ca..0000000
--- a/Source/ArachnaeSwarm/EventSystem/Letter_EventChoice.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using RimWorld;
-using RimWorld.QuestGen;
-using System;
-using System.Collections.Generic;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public class Letter_EventChoice : ChoiceLetter
- {
- // These fields are now inherited from the base Letter class
- // public string letterLabel;
- // public string letterTitle;
- // public string letterText;
- public List options;
- public new Quest quest;
-
- public override IEnumerable Choices
- {
- get
- {
- if (options.NullOrEmpty())
- {
- yield break;
- }
-
- foreach (var optionDef in options)
- {
- var currentOption = optionDef;
- Action choiceAction = delegate
- {
- if (!currentOption.optionEffects.NullOrEmpty())
- {
- foreach (var conditionalEffect in currentOption.optionEffects)
- {
- string reason;
- if (AreConditionsMet(conditionalEffect.conditions, out reason))
- {
- conditionalEffect.Execute(null);
- }
- }
- }
- if (quest != null && !quest.hidden && !quest.Historical)
- {
- quest.End(QuestEndOutcome.Success);
- }
- Find.LetterStack.RemoveLetter(this);
- };
-
- var diaOption = new DiaOption(currentOption.label)
- {
- action = choiceAction,
- resolveTree = true
- };
- yield return diaOption;
- }
- }
- }
-
- public override bool CanDismissWithRightClick => false;
-
- private bool AreConditionsMet(List conditions, out string reason)
- {
- reason = "";
- if (conditions.NullOrEmpty())
- {
- return true;
- }
-
- foreach (var condition in conditions)
- {
- if (!condition.IsMet(out string singleReason))
- {
- reason = singleReason;
- return false;
- }
- }
- return true;
- }
-
- public override void ExposeData()
- {
- base.ExposeData();
- // Scribe_Values.Look(ref letterLabel, "letterLabel"); // Now uses base.label
- // Scribe_Values.Look(ref letterTitle, "letterTitle"); // Now uses base.title
- // Scribe_Values.Look(ref letterText, "letterText"); // Now uses base.text
- Scribe_Collections.Look(ref options, "options", LookMode.Deep);
- if (Scribe.mode != LoadSaveMode.Saving || quest != null)
- {
- Scribe_References.Look(ref quest, "quest");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/EventSystem/QuestNode_Root_EventLetter.cs b/Source/ArachnaeSwarm/EventSystem/QuestNode_Root_EventLetter.cs
deleted file mode 100644
index 31b318a..0000000
--- a/Source/ArachnaeSwarm/EventSystem/QuestNode_Root_EventLetter.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using RimWorld;
-using RimWorld.QuestGen;
-using System;
-using System.Collections.Generic;
-using Verse;
-
-namespace ArachnaeSwarm
-{
- public class QuestNode_Root_EventLetter : QuestNode
- {
- // Fields to be set from the QuestScriptDef XML
- public SlateRef letterLabel;
- public SlateRef letterTitle;
- public SlateRef letterText;
- public List options = new List ();
-
- // This is a root node, so it doesn't have a parent signal.
- // It runs immediately when the quest starts.
- protected override void RunInt()
- {
- // Get the current slate
- Slate slate = QuestGen.slate;
-
- var letter = (Letter_EventChoice)LetterMaker.MakeLetter(DefDatabase.GetNamed("ARA_EventChoiceLetter"));
- letter.Label = letterLabel.GetValue(slate);
- letter.title = letterTitle.GetValue(slate);
- letter.Text = letterText.GetValue(slate);
- letter.options = options;
- letter.quest = QuestGen.quest;
- letter.lookTargets = slate.Get("lookTargets");
-
- Find.LetterStack.ReceiveLetter(letter);
- }
-
- protected override bool TestRunInt(Slate slate)
- {
- // This node can always run as long as the slate refs are valid.
- // We can add more complex checks here if needed.
- return true;
- }
-
- // Inner class to hold option data from XML
- public class Option
- {
- public string label;
- public List optionEffects;
- }
- }
-}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffCompProperties_ProductionQueue.cs b/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffCompProperties_ProductionQueue.cs
index 8584124..2475fc9 100644
--- a/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffCompProperties_ProductionQueue.cs
+++ b/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffCompProperties_ProductionQueue.cs
@@ -128,7 +128,6 @@ namespace ArachnaeSwarm
count = entry.count,
cost = entry.cost,
cooldownTicks = entry.cooldownTicks,
- conditions = entry.conditions?.ToList(), // 复制条件列表
customInfo = entry.customInfo
};
entryMap[entry.pawnKind] = newEntry;
diff --git a/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffComp_ProductionQueue.cs b/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffComp_ProductionQueue.cs
index f78a4aa..1f148d2 100644
--- a/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffComp_ProductionQueue.cs
+++ b/Source/ArachnaeSwarm/Hediffs/ARA_ProductionQueue/HediffComp_ProductionQueue.cs
@@ -32,37 +32,12 @@ namespace ArachnaeSwarm
foreach (var entry in queue)
{
- // 检查前置条件
- if (CheckEntryConditions(entry, pawn))
- {
- availableQueue.Add(entry);
- }
+ availableQueue.Add(entry);
}
return availableQueue;
}
- ///
- /// 检查条目条件是否满足
- ///
- private bool CheckEntryConditions(PawnProductionEntry entry, Pawn pawn)
- {
- // 检查自定义条件
- if (!entry.conditions.NullOrEmpty())
- {
- foreach (var condition in entry.conditions)
- {
- string reason;
- if (!condition.IsMet(out reason))
- {
- return false;
- }
- }
- }
-
- return true;
- }
-
///
/// 根据PawnKindDef查找生产队列条目
///
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_FeedWithHoney/ThinkNode_JobGiver_FeedWithHoney.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_FeedWithHoney/ThinkNode_JobGiver_FeedWithHoney.cs
index 050efbd..a207475 100644
--- a/Source/ArachnaeSwarm/Jobs/JobDriver_FeedWithHoney/ThinkNode_JobGiver_FeedWithHoney.cs
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_FeedWithHoney/ThinkNode_JobGiver_FeedWithHoney.cs
@@ -98,7 +98,7 @@ namespace ArachnaeSwarm
return true;
// 检查是否和喂养者同一派系
- if (target.Faction != null && target.Faction == feeder.Faction)
+ if (target.Faction != null && target.Faction == feeder.Faction && !target.IsAnimal)
return true;
return false;
diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs
index adf2f2d..c5b3469 100644
--- a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs
+++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Reflection;
using UnityEngine;
using Verse;
+using Verse.AI;
using Verse.AI.Group;
namespace ArachnaeSwarm
@@ -654,7 +655,13 @@ namespace ArachnaeSwarm
}
if (parent is Pawn p && p.GetLord() != null)
+ {
p.GetLord().AddPawn(pawn);
+ if (pawn.mindState.duty == null && p.mindState.duty != null)
+ {
+ pawn.mindState.duty = p.mindState.duty;
+ }
+ }
if (!AutoProps.freeProduction)
{
diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProducedByMechCarrier.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProducedByMechCarrier.cs
index d2e3faa..7db8046 100644
--- a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProducedByMechCarrier.cs
+++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProducedByMechCarrier.cs
@@ -230,11 +230,19 @@ namespace ArachnaeSwarm
// 检查生产者是否仍然有效
if (producer != null && (producer.Destroyed || (producer is Pawn p && (p.Dead || p.Downed))))
{
- Log.Warning($"生产者无效: {producer?.LabelCap}, 清除引用");
producer = null;
producerComp = null;
}
-
+ else if (producer != null && producer is Pawn)
+ {
+ Pawn pawnProducer = producer as Pawn;
+ Pawn creation = parent as Pawn;
+ if (creation.mindState.duty == null && pawnProducer.mindState.duty != null)
+ {
+ creation.mindState.duty = pawnProducer.mindState.duty;
+ }
+ }
+
// 检查自身状态
CheckSelfStatus();
}
@@ -252,7 +260,6 @@ namespace ArachnaeSwarm
{
wasDead = true;
deathTick = Find.TickManager.TicksGame;
- Log.Message($"子单位死亡: {pawn.LabelCap}, 准备通知生产者");
}
// 死亡后延迟清理
diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/PawnProductionEntry.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/PawnProductionEntry.cs
index 6d709c0..d42639f 100644
--- a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/PawnProductionEntry.cs
+++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/PawnProductionEntry.cs
@@ -26,9 +26,6 @@ namespace ArachnaeSwarm
// Optional: custom information for display
public string customInfo;
- // Optional: conditions that must be met for this entry to be available
- public List conditions;
-
// Optional: priority (lower number = higher priority)
public int priority = 0;
@@ -76,21 +73,6 @@ namespace ArachnaeSwarm
return false;
}
}
-
- // 检查自定义条件
- if (!conditions.NullOrEmpty())
- {
- foreach (var condition in conditions)
- {
- string conditionReason;
- if (!condition.IsMet(out conditionReason))
- {
- reason = conditionReason;
- return false;
- }
- }
- }
-
return true;
}
@@ -106,7 +88,6 @@ namespace ArachnaeSwarm
cooldownTicks = cooldownTicks,
cost = cost,
customInfo = customInfo,
- conditions = conditions?.ToList(), // 深拷贝条件列表
priority = priority,
weight = weight,
enabled = enabled,
diff --git a/非公开资源/Content/Textures/Things/ARAQueen_Infector/Naked_Thin_east.sai2 b/非公开资源/Content/Textures/Things/ARAQueen_Infector/Naked_Thin_east.sai2
new file mode 100644
index 0000000..47e2ad5
Binary files /dev/null and b/非公开资源/Content/Textures/Things/ARAQueen_Infector/Naked_Thin_east.sai2 differ
diff --git a/非公开资源/Content/脑虫.sai2 b/非公开资源/Content/脑虫.sai2
index 9dc847b..590df68 100644
Binary files a/非公开资源/Content/脑虫.sai2 and b/非公开资源/Content/脑虫.sai2 differ
diff --git a/非公开资源/Content/111.sai2 b/非公开资源/Content/脑虫2.sai2
similarity index 53%
rename from 非公开资源/Content/111.sai2
rename to 非公开资源/Content/脑虫2.sai2
index 1f8fb10..b43b5c8 100644
Binary files a/非公开资源/Content/111.sai2 and b/非公开资源/Content/脑虫2.sai2 differ