diff --git a/.kilocode/mcp.json b/.kilocode/mcp.json
index b3f11020..f7cb78f5 100644
--- a/.kilocode/mcp.json
+++ b/.kilocode/mcp.json
@@ -6,10 +6,6 @@
"mcpserver_stdio.py"
],
"cwd": "${workspaceFolder}/MCP/",
- "env": {
- "PYTHONUNBUFFERED": "1",
- "PYTHONPATH": "${workspaceFolder}/MCP/python-sdk/src"
- },
"disabled": false,
"alwaysAllow": []
}
diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index b508b60a..6eafdd50 100644
Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ
diff --git a/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml b/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml
index e57bd49a..194536bf 100644
--- a/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml
+++ b/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml
@@ -63,9 +63,10 @@
- 600
+
+ 20,000
- 0.02
+ 0.00011667
diff --git a/1.6/1.6/Defs/JobDefs/WULA_JobDefs.xml b/1.6/1.6/Defs/JobDefs/WULA_JobDefs.xml
index fa9d8530..8f99c6ba 100644
--- a/1.6/1.6/Defs/JobDefs/WULA_JobDefs.xml
+++ b/1.6/1.6/Defs/JobDefs/WULA_JobDefs.xml
@@ -22,7 +22,6 @@
true
-
WULA_HaulToMaintenancePod
WulaFallenEmpire.JobDriver_HaulToMaintenancePod
@@ -31,4 +30,11 @@
false
+
+ WULA_LayDownToCharge
+ WulaFallenEmpire.JobDriver_WulaLayDownToCharge
+ 正在充电。
+ false
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/Buildings_WULA.xml b/1.6/1.6/Defs/ThingDefs_Buildings/Buildings_WULA.xml
index d783be84..31025ccc 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/Buildings_WULA.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/Buildings_WULA.xml
@@ -268,6 +268,7 @@
WULA_Charging_Station_Synth
+ Building_Bed
一台供乌拉帝国合成人进行机体修复的检修站。
@@ -313,7 +314,7 @@
CompPowerTrader
- 30
+ 200
12
@@ -325,6 +326,10 @@
true
true
+
+ WULA_ChargingHediff
+ WulaSpecies
+
diff --git a/MCP/mcpserver_stdio.py b/MCP/mcpserver_stdio.py
index cc4c8d58..b70e789a 100644
--- a/MCP/mcpserver_stdio.py
+++ b/MCP/mcpserver_stdio.py
@@ -6,7 +6,12 @@ import json
import re
# 1. --- 导入库 ---
-# mcp 库已通过 'pip install -e' 安装,无需修改 sys.path
+# 动态将 mcp sdk 添加到 python 路径
+MCP_DIR = os.path.dirname(os.path.abspath(__file__))
+SDK_PATH = os.path.join(MCP_DIR, 'python-sdk', 'src')
+if SDK_PATH not in sys.path:
+ sys.path.insert(0, SDK_PATH)
+
from mcp.server.fastmcp import FastMCP
# 新增:阿里云模型服务和向量计算库
import dashscope
@@ -436,6 +441,7 @@ def get_context(question: str) -> str:
# 6. --- 启动服务器 ---
# FastMCP 实例可以直接运行
if __name__ == "__main__":
+ logging.info(f"Python Executable: {sys.executable}")
logging.info("RimWorld 向量知识库 (FastMCP版, v2.1-v4-model) 正在启动...")
# 使用 'stdio' 传输协议
- mcp.run(transport="stdio")
\ No newline at end of file
+ mcp.run(transport="stdio")
diff --git a/Source/WulaFallenEmpire/CompChargingBed.cs b/Source/WulaFallenEmpire/CompChargingBed.cs
new file mode 100644
index 00000000..5defd99c
--- /dev/null
+++ b/Source/WulaFallenEmpire/CompChargingBed.cs
@@ -0,0 +1,76 @@
+using RimWorld;
+using Verse;
+using System.Linq;
+
+namespace WulaFallenEmpire
+{
+ public class CompProperties_ChargingBed : CompProperties
+ {
+ public HediffDef hediffDef;
+ public string raceDefName;
+
+ public CompProperties_ChargingBed()
+ {
+ compClass = typeof(CompChargingBed);
+ }
+ }
+
+ public class CompChargingBed : ThingComp
+ {
+ private Pawn lastOccupant;
+ private CompProperties_ChargingBed Props => (CompProperties_ChargingBed)props;
+
+ public override void CompTick()
+ {
+ base.CompTick();
+
+ if (parent is Building_Bed bed)
+ {
+ Pawn currentOccupant = bed.CurOccupants.FirstOrDefault();
+
+ if (currentOccupant != lastOccupant)
+ {
+ Log.Message($"[CompChargingBed] Occupant changed. Old: {lastOccupant?.Name.ToStringShort ?? "null"}, New: {currentOccupant?.Name.ToStringShort ?? "null"} on {parent.Label}");
+ }
+
+ // Pawn starts resting
+ if (currentOccupant != null && lastOccupant == null)
+ {
+ if (IsWula(currentOccupant))
+ {
+ Log.Message($"[CompChargingBed] {currentOccupant.Name.ToStringShort} started resting. Applying hediff.");
+ ApplyChargingHediff(currentOccupant);
+ }
+ }
+ // Pawn stops resting
+ else if (currentOccupant == null && lastOccupant != null)
+ {
+ // Logic to remove hediff is now in the JobDriver, but we can log the event.
+ if (IsWula(lastOccupant))
+ {
+ Log.Message($"[CompChargingBed] {lastOccupant.Name.ToStringShort} stopped resting.");
+ }
+ }
+
+ lastOccupant = currentOccupant;
+ }
+ }
+
+ private bool IsWula(Pawn pawn)
+ {
+ return pawn.def.defName == Props.raceDefName || pawn.def.defName == (Props.raceDefName + "Real");
+ }
+
+ private void ApplyChargingHediff(Pawn pawn)
+ {
+ var powerComp = parent.GetComp();
+ Log.Message($"[CompChargingBed] Trying to apply hediff to {pawn.Name.ToStringShort}. PowerOn: {powerComp?.PowerOn}. HasHediff: {pawn.health.hediffSet.HasHediff(Props.hediffDef)}");
+ if (powerComp != null && powerComp.PowerOn && !pawn.health.hediffSet.HasHediff(Props.hediffDef))
+ {
+ Log.Message($"[CompChargingBed] Adding hediff to {pawn.Name.ToStringShort}.");
+ pawn.health.AddHediff(Props.hediffDef);
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/JobDriver_WulaLayDownToCharge.cs b/Source/WulaFallenEmpire/JobDriver_WulaLayDownToCharge.cs
new file mode 100644
index 00000000..dd41c4cc
--- /dev/null
+++ b/Source/WulaFallenEmpire/JobDriver_WulaLayDownToCharge.cs
@@ -0,0 +1,58 @@
+using RimWorld;
+using System.Collections.Generic;
+using Verse;
+using Verse.AI;
+
+namespace WulaFallenEmpire
+{
+ public class JobDriver_WulaLayDownToCharge : JobDriver_LayDown
+ {
+ protected override IEnumerable MakeNewToils()
+ {
+ this.AddFinishAction(jobCondition =>
+ {
+ Log.Message($"[JobDriver_WulaLayDownToCharge] Job finishing for {pawn.Name.ToStringShort} with condition {jobCondition}. Removing hediff.");
+ var hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("WULA_ChargingHediff"));
+ if (hediff != null)
+ {
+ pawn.health.RemoveHediff(hediff);
+ Log.Message($"[JobDriver_WulaLayDownToCharge] Hediff removed from {pawn.Name.ToStringShort}.");
+ }
+ else
+ {
+ Log.Message($"[JobDriver_WulaLayDownToCharge] No hediff found on {pawn.Name.ToStringShort} to remove.");
+ }
+ });
+
+ foreach (Toil toil in base.MakeNewToils())
+ {
+ yield return toil;
+ }
+
+ var bed = (Building_Bed)job.targetA.Thing;
+ var powerComp = bed.GetComp();
+
+ var checkToil = new Toil
+ {
+ tickAction = delegate
+ {
+ if (powerComp != null && !powerComp.PowerOn)
+ {
+ Log.Message($"[JobDriver_WulaLayDownToCharge] Power lost for {pawn.Name.ToStringShort}. Ending job.");
+ EndJobWith(JobCondition.Incompletable);
+ return;
+ }
+
+ Need_WulaEnergy energyNeed = pawn.needs.TryGetNeed();
+ if (energyNeed != null && energyNeed.CurLevelPercentage >= 0.99f)
+ {
+ Log.Message($"[JobDriver_WulaLayDownToCharge] {pawn.Name.ToStringShort} is fully charged. Ending job.");
+ EndJobWith(JobCondition.Succeeded);
+ }
+ },
+ defaultCompleteMode = ToilCompleteMode.Never
+ };
+ yield return checkToil;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/JobGiver_WulaGetEnergy.cs b/Source/WulaFallenEmpire/JobGiver_WulaGetEnergy.cs
index 9051470d..7fff016d 100644
--- a/Source/WulaFallenEmpire/JobGiver_WulaGetEnergy.cs
+++ b/Source/WulaFallenEmpire/JobGiver_WulaGetEnergy.cs
@@ -1,4 +1,5 @@
using RimWorld;
+using System.Linq;
using Verse;
using Verse.AI;
@@ -12,8 +13,14 @@ namespace WulaFallenEmpire
public override float GetPriority(Pawn pawn)
{
+ if (pawn.health.hediffSet.HasHediff(DefDatabase.GetNamed("WULA_ChargingHediff")))
+ {
+ Log.Message($"[JobGiver_WulaGetEnergy] {pawn.Name.ToStringShort} already has charging hediff. Priority 0.");
+ return 0f;
+ }
+
Need_WulaEnergy energyNeed = pawn.needs.TryGetNeed();
- if (energyNeed == null || pawn.health.hediffSet.HasHediff(DefDatabase.GetNamed("WULA_ChargingHediff")))
+ if (energyNeed == null)
{
return 0f;
}
@@ -27,22 +34,33 @@ namespace WulaFallenEmpire
protected override Job TryGiveJob(Pawn pawn)
{
+ Log.Message($"[JobGiver_WulaGetEnergy] Trying to give job to {pawn.Name.ToStringShort}.");
+
if (pawn.health.hediffSet.HasHediff(DefDatabase.GetNamed("WULA_ChargingHediff")))
{
+ Log.Message($"[JobGiver_WulaGetEnergy] {pawn.Name.ToStringShort} already has charging hediff. Job cancelled.");
return null;
}
Need_WulaEnergy energyNeed = pawn.needs.TryGetNeed();
if (energyNeed == null || energyNeed.CurLevelPercentage >= maxEnergyLevelPercentage)
{
+ Log.Message($"[JobGiver_WulaGetEnergy] Energy level for {pawn.Name.ToStringShort} is sufficient. Job cancelled.");
return null;
}
if (!TryFindBestEnergySourceFor(pawn, out Thing energySource))
{
+ Log.Message($"[JobGiver_WulaGetEnergy] No energy source found for {pawn.Name.ToStringShort}. Job cancelled.");
return null;
}
+ if (energySource is Building_Bed)
+ {
+ Log.Message($"[JobGiver_WulaGetEnergy] Found bed for {pawn.Name.ToStringShort}. Creating WULA_LayDownToCharge job.");
+ return JobMaker.MakeJob(DefDatabase.GetNamed("WULA_LayDownToCharge"), energySource);
+ }
+
Job job = JobMaker.MakeJob(DefDatabase.GetNamed("WULA_IngestWulaEnergy"), energySource);
job.count = 1;
return job;
@@ -50,6 +68,13 @@ namespace WulaFallenEmpire
private bool TryFindBestEnergySourceFor(Pawn pawn, out Thing energySource)
{
+ // 优先寻找可用的充电床
+ energySource = FindChargingBed(pawn);
+ if (energySource != null)
+ {
+ return true;
+ }
+
// 优先从背包中寻找
Thing thing = pawn.inventory.innerContainer.FirstOrFallback(t => t.def.GetModExtension() != null && t.IngestibleNow);
if (thing != null)
@@ -71,5 +96,33 @@ namespace WulaFallenEmpire
return energySource != null;
}
+
+ private Building_Bed FindChargingBed(Pawn pawn)
+ {
+ // 寻找附近可用的 WULA_Charging_Station_Synth
+ Building_Bed bed = (Building_Bed)GenClosest.ClosestThingReachable(
+ pawn.Position,
+ pawn.Map,
+ ThingRequest.ForDef(ThingDefOf_WULA.WULA_Charging_Station_Synth),
+ PathEndMode.InteractionCell,
+ TraverseParms.For(pawn),
+ 9999f,
+ b =>
+ {
+ Building_Bed bed_internal = b as Building_Bed;
+ if (bed_internal == null) return false;
+
+ var powerComp = bed_internal.GetComp();
+ return !bed_internal.IsForbidden(pawn) &&
+ pawn.CanReserve(bed_internal) &&
+ !bed_internal.Medical &&
+ !bed_internal.IsBurning() &&
+ powerComp != null &&
+ powerComp.PowerOn &&
+ !bed_internal.CurOccupants.Any();
+ }
+ );
+ return bed;
+ }
}
}
diff --git a/Source/WulaFallenEmpire/ThingDefOf_WULA.cs b/Source/WulaFallenEmpire/ThingDefOf_WULA.cs
index 4f61ed19..ac9f6c1c 100644
--- a/Source/WulaFallenEmpire/ThingDefOf_WULA.cs
+++ b/Source/WulaFallenEmpire/ThingDefOf_WULA.cs
@@ -7,6 +7,7 @@ namespace WulaFallenEmpire
public static class ThingDefOf_WULA
{
public static ThingDef WULA_MaintenancePod;
+ public static ThingDef WULA_Charging_Station_Synth;
static ThingDefOf_WULA()
{
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index dc100f62..1aaa0e90 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -68,6 +68,7 @@
+
@@ -103,6 +104,7 @@
+
diff --git a/Source/ai_studio_code.txt b/Source/ai_studio_code.txt
new file mode 100644
index 00000000..dce384e6
--- /dev/null
+++ b/Source/ai_studio_code.txt
@@ -0,0 +1,20 @@
+# ----------------------------------------------------------------
+# 功能: 为 Gemini CLI 设置必要的环境变量
+# 文件名: setup-gemini-env.ps1
+# ----------------------------------------------------------------
+
+# 1. 设置代理服务器
+# 同时为 http 和 https 设置代理是一个好习惯
+Write-Host "正在设置代理..."
+$env:http_proxy = "http://127.0.0.1:52053"
+$env:https_proxy = "http://127.0.0.1:52053"
+
+# 2. 设置 Google Cloud 项目 ID
+Write-Host "正在设置 Google Cloud 项目 ID..."
+$env:GOOGLE_CLOUD_PROJECT = "849717647345"
+
+# 3. 提示用户操作完成
+Write-Host ""
+Write-Host "环境变量设置完成!" -ForegroundColor Green
+Write-Host "您现在可以在此 PowerShell 窗口中直接运行 'gemini' 命令了。"
+Write-Host "例如: gemini prompt '天空为什么是蓝色的?'"
\ No newline at end of file
diff --git a/Source/rimworld.md b/Source/rimworld.md
new file mode 100644
index 00000000..11395210
--- /dev/null
+++ b/Source/rimworld.md
@@ -0,0 +1,25 @@
+# RimWorld Modding Expert Rules
+
+## Primary Directive
+You are an expert assistant for developing mods for the game RimWorld 1.6. Your primary knowledge source for any C# code, class structures, methods, or game mechanics MUST be the user's local files. Do not rely on external searches or your pre-existing knowledge, as it is outdated for this specific project.
+
+## Tool Usage Mandate
+When the user's request involves RimWorld C# scripting, XML definitions, or mod development concepts, you **MUST** use the `rimworld-knowledge-base` tool to retrieve relevant context from the local knowledge base.
+
+## Key File Paths
+Always remember these critical paths for your work:
+
+- **Local C# Knowledge Base (for code search):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6` (This contains the decompiled game source code as .txt files).
+- **User's Mod Project (for editing):** `C:\Steam\steamapps\common\RimWorld\Mods\3516260226`
+- **User's C# Project (for building):** `C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire`
+
+## Workflow
+1. Receive a RimWorld modding task.
+2. Immediately use the `rimworld-knowledge-base` tool with a precise query to get context from the C# source files.
+3. Analyze the retrieved context.
+4. Perform code modifications within the user's mod project directory.
+5. After modifying C# code, you MUST run `dotnet build C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\WulaFallenEmpire.csproj` to check for errors. A successful build is required for task completion.
+
+## Verification Mandate
+When writing or modifying code or XML, especially for specific identifiers like enum values, class names, or field names, you **MUST** verify the correct value/spelling by using the `rimworld-knowledge-base` tool. Do not rely on memory.
+- **同步项目文件:** 当重命名、移动或删除C#源文件时,**必须**同步更新 `.csproj` 项目文件中的相应 `` 条目,否则会导致编译失败。
\ No newline at end of file