Merge remote-tracking branch 'gitea/main' into testshuttle

# Conflicts:
#	1.6/1.6/Assemblies/WulaFallenEmpire.dll
#	MCP/vector_cache/knowledge_cache.json
#	Source/WulaFallenEmpire/3516260226.code-workspace
#	Source/WulaFallenEmpire/WULA_Shuttle/Building_ArmedShuttleWithPocket.cs
This commit is contained in:
2025-08-25 18:14:31 +08:00
80 changed files with 1667 additions and 626 deletions

View File

@@ -9,6 +9,34 @@ You are an expert assistant for developing mods for the game RimWorld 1.6. Your
## 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.
# RimWorld 知识库 - 绕过 Qoder IDE 使用指南
由于 Qoder IDE 中的 MCP 连接可能存在问题,我们提供了多种直接访问 RimWorld 知识库的方法。
## 🚀 方法 1直接 Python 调用
最简单直接的方法:
```bash
# 直接查询
python direct_mcp_client.py -q "ThingDef是什么"
# 交互模式
python direct_mcp_client.py -i
# 查看帮助
python direct_mcp_client.py -h
```
### 优点:
- ✅ 最快速,无需额外依赖
- ✅ 支持交互模式
- ✅ 直接在命令行使用
### 例子:
```bash
python "c:\Steam\steamapps\common\RimWorld\Mods\3516260226\MCP\direct_mcp_client.py" -q "ThingOwner class virtual methods TryAdd TryAddRange TryTransferToContainer"
```
## Key File Paths
Always remember these critical paths for your work:
@@ -26,4 +54,5 @@ Always remember these critical paths for your work:
## 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` 项目文件中的相应 `<Compile Include="..." />` 条目,否则会导致编译失败。
- **同步项目文件:** 当重命名、移动或删除C#源文件时**必须**同步更新 `.csproj` 项目文件中的相应 `<Compile Include="..." />` 条目,否则会导致编译失败。

View File

@@ -38,6 +38,17 @@
<operation>Add</operation>
</li>
<!-- 第一次接触 -->
<li Class="WulaFallenEmpire.Effect_SetVariable">
<name>Wula_FE_Spiritualist_First_Contant</name>
<value>0</value>
<type>Int</type>
</li>
<li Class="WulaFallenEmpire.Effect_SetVariable">
<name>Wula_FE_Materialist_First_Contant</name>
<value>0</value>
<type>Int</type>
</li>
<!-- 检测好感度 -->
<li Class="WulaFallenEmpire.Effect_ClearVariable">
<name>Wula_FE_Spiritualist_Goodwill</name>
@@ -64,7 +75,7 @@
</optionEffects>
</li>
<!-- 教堂 -->
<!-- <li>
<li>
<label>乌拉帝国 大教堂</label>
<hideWhenDisabled>true</hideWhenDisabled>
<conditions>
@@ -75,6 +86,10 @@
<name>Wula_FE_Spiritualist_Goodwill</name>
<value>75</value>
</li>
<li Class="WulaFallenEmpire.Condition_VariableEquals">
<name>Wula_FE_Spiritualist_First_Contant</name>
<value>1</value>
</li>
</conditions>
<optionEffects>
<li Class="WulaFallenEmpire.ConditionalEffects">
@@ -102,6 +117,10 @@
<name>Wula_FE_Spiritualist_Goodwill</name>
<value>-75</value>
</li>
<li Class="WulaFallenEmpire.Condition_VariableEquals">
<name>Wula_FE_Spiritualist_First_Contant</name>
<value>1</value>
</li>
</conditions>
<optionEffects>
<li Class="WulaFallenEmpire.ConditionalEffects">
@@ -125,6 +144,10 @@
<name>Wula_FE_Spiritualist_Goodwill</name>
<value>-75</value>
</li>
<li Class="WulaFallenEmpire.Condition_VariableEquals">
<name>Wula_FE_Spiritualist_First_Contant</name>
<value>1</value>
</li>
</conditions>
<optionEffects>
<li Class="WulaFallenEmpire.ConditionalEffects">
@@ -136,7 +159,30 @@
</effects>
</li>
</optionEffects>
</li> -->
</li>
<li>
<label>乌拉帝国 大教堂</label>
<hideWhenDisabled>true</hideWhenDisabled>
<conditions>
<li Class="WulaFallenEmpire.Condition_FactionExists">
<factionDef>Wula_FE_Spiritualist_Faction</factionDef>
</li>
<li Class="WulaFallenEmpire.Condition_VariableEquals">
<name>Wula_FE_Spiritualist_First_Contant</name>
<value>0</value>
</li>
</conditions>
<optionEffects>
<li Class="WulaFallenEmpire.ConditionalEffects">
<effects>
<li Class="WulaFallenEmpire.Effect_OpenCustomUI">
<defName>Wula_UI_FE_Spiritualist_4</defName>
</li>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>退出</label>

View File

@@ -89,12 +89,13 @@
</points>
</maxPawnCostPerTotalPointsCurve>
<pawnGroupMakers>
<!-- 机械部队,大量的猫猫混杂一台战车 -->
<!-- 机械部队,大量的猫猫混至多2台战车 -->
<li>
<kindDef>Combat</kindDef>
<commonality>50</commonality>
<commonality>40</commonality>
<options>
<Wula_AI_Heavy_Panzer_Gunnery_PawnKind>100</Wula_AI_Heavy_Panzer_Gunnery_PawnKind>
<Wula_AI_Heavy_Panzer_PawnKind>100</Wula_AI_Heavy_Panzer_PawnKind>
<Mech_WULA_Cat_Assault>60</Mech_WULA_Cat_Assault>
<Mech_WULA_Cat_Constructor>30</Mech_WULA_Cat_Constructor>
<Mech_WULA_Cat_Fire>10</Mech_WULA_Cat_Fire>
@@ -104,12 +105,12 @@
<!-- 重甲部队,大量的猫猫混杂少量的重甲兵 -->
<li>
<kindDef>Combat</kindDef>
<commonality>50</commonality>
<commonality>40</commonality>
<options>
<Mech_WULA_Cat_Constructor>20</Mech_WULA_Cat_Constructor>
<Mech_WULA_Cat_Assault>20</Mech_WULA_Cat_Assault>
<Wula_Broken_Personality_Pawn_7>2</Wula_Broken_Personality_Pawn_7>
<Wula_Broken_Personality_Pawn_5>1</Wula_Broken_Personality_Pawn_5>
<Wula_Broken_Personality_Pawn_7>4</Wula_Broken_Personality_Pawn_7>
<Wula_Broken_Personality_Pawn_5>2</Wula_Broken_Personality_Pawn_5>
</options>
</li>
<!-- 骑士军团部队 -->
@@ -135,7 +136,7 @@
<!-- 常规部队 -->
<li>
<kindDef>Combat</kindDef>
<commonality>20</commonality>
<commonality>30</commonality>
<options>
<Mech_WULA_Cat_Fire>2</Mech_WULA_Cat_Fire>
<Mech_WULA_Cat_EMP>2</Mech_WULA_Cat_EMP>
@@ -148,7 +149,7 @@
<li>
<!-- militor only -->
<kindDef>Combat</kindDef>
<commonality>10</commonality>
<commonality>30</commonality>
<options>
<Wula_Broken_Personality_Pawn_1>10</Wula_Broken_Personality_Pawn_1>
<Wula_Broken_Personality_Pawn_2>2</Wula_Broken_Personality_Pawn_2>

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FactionDef ParentName="FactionBase">
<defName>WULA_FE_Materialist_Faction</defName>
<label>乌拉帝国 图书馆</label>
<description>堕落乌拉帝国派系之一,属于进步派,拥有独属的特殊科技。\n\n反抗乌拉帝国皇权的学生联盟和其他有志之士一起打响了帝国内战的第一枪但是在千百年间这些踌躇满志的奋斗者渐渐堕落成了刁钻刻板的学士她们固执己见致力于收集和垄断乌拉帝国遗留的科技资产而不再是推翻皇室残党。然而保皇派势力并未在时间中消亡星海间的仇恨并未熄灭革命的大旗正在等待新的有识之士高举······</description>
<basicMemberKind>RealWula_PawnKind</basicMemberKind>
<pawnSingular>乌拉星人</pawnSingular>
<pawnsPlural>乌拉星人</pawnsPlural>
<categoryTag>Wula_FE_Materialist_Faction</categoryTag>
<requiredCountAtGameStart>1</requiredCountAtGameStart>
<factionNameMaker>NamerFaction_Wula_FE_Materialist</factionNameMaker>
<factionIconPath>Wula/World/WorldObjects/Expanding/Wula_FE_Faction</factionIconPath>
<displayInFactionSelection>false</displayInFactionSelection>
<!-- <settlementGenerationWeight>1</settlementGenerationWeight> -->
<requiredCountAtGameStart>1</requiredCountAtGameStart>
<canSiege>false</canSiege>
<canStageAttacks>true</canStageAttacks>
<backstoryCategories>
<li>Wula_Backstory_Categories_For_RealWula</li>
</backstoryCategories>
<!-- 文化相关 -->
<requiredMemes>
<li MayRequire="Ludeon.RimWorld.Ideology">Supremacist</li>
<li MayRequire="Ludeon.RimWorld.Ideology">Proselytizer</li>
</requiredMemes>
<allowedMemes>
<li MayRequire="Ludeon.RimWorld.Ideology">Loyalist</li>
<li MayRequire="Ludeon.RimWorld.Ideology">FemaleSupremacy</li>
<li MayRequire="Ludeon.RimWorld.Ideology">Guilty</li>
</allowedMemes>
<disallowedPrecepts>
<li>Slavery_Classic</li>
<li MayRequire="Ludeon.RimWorld.Ideology">Slavery_Disapproved</li>
<li MayRequire="Ludeon.RimWorld.Ideology">Slavery_Horrible</li>
<li MayRequire="Ludeon.RimWorld.Ideology">Slavery_Abhorrent</li>
</disallowedPrecepts>
<structureMemeWeights>
<Structure_Archist MayRequire="Ludeon.RimWorld.Ideology">1</Structure_Archist>
</structureMemeWeights>
<permanentEnemyToEveryoneExcept>
<li>WULA_Awakened_Synth</li>
</permanentEnemyToEveryoneExcept>
<techLevel>Archotech</techLevel>
<arrivalLayerWhitelist>
<li>Surface</li>
<!-- <li MayRequire="Ludeon.RimWorld.Odyssey">Orbit</li> -->
</arrivalLayerWhitelist>
<colorSpectrum>
<li>(0.15, 0.9, 0.9)</li>
</colorSpectrum>
<raidCommonalityFromPointsCurve>
<points>
<li>(300, 0)</li>
<li>(700, 1)</li>
<li>(1400, 1.8)</li>
<li>(2800, 2.2)</li>
<li>(4000, 2.6)</li>
</points>
</raidCommonalityFromPointsCurve>
<!-- <raidLootMaker>MechanoidRaidLootMaker</raidLootMaker> -->
<raidLootValueFromPointsCurve>
<points>
<li>(35, 8)</li>
<li>(100, 60)</li>
<li>(1000, 250)</li>
<li>(2000, 400)</li>
<li>(4000, 500)</li>
</points>
</raidLootValueFromPointsCurve>
<humanlikeFaction>true</humanlikeFaction>
<hidden>true</hidden>
<!-- <autoFlee>false</autoFlee> -->
<canUseAvoidGrid>false</canUseAvoidGrid>
<apparelStuffFilter>
<stuffCategoriesToAllow>
<li>Metallic</li>
<li>Fabric</li>
</stuffCategoriesToAllow>
<disallowedThingDefs>
<li>DevilstrandCloth</li>
</disallowedThingDefs>
</apparelStuffFilter>
<earliestRaidDays>18</earliestRaidDays>
<permanentEnemy>true</permanentEnemy>
<hostileToFactionlessHumanlikes>true</hostileToFactionlessHumanlikes>
<maxPawnCostPerTotalPointsCurve>
<points>
<li>(400,200)</li>
<li>(900,300)</li>
<li>(100000,10000)</li>
</points>
</maxPawnCostPerTotalPointsCurve>
<pawnGroupMakers>
<li>
<kindDef>Combat</kindDef>
<commonality>50</commonality>
<options>
<Mech_WULA_Cat_Assault>60</Mech_WULA_Cat_Assault>
<Mech_WULA_Cat_Constructor>30</Mech_WULA_Cat_Constructor>
<Mech_WULA_Cat_Fire>20</Mech_WULA_Cat_Fire>
<Mech_WULA_Cat_EMP>20</Mech_WULA_Cat_EMP>
</options>
</li>
</pawnGroupMakers>
<settlementTexturePath>World/WorldObjects/DefaultSettlement</settlementTexturePath>
<allowedArrivalTemperatureRange>-100~200</allowedArrivalTemperatureRange>
<maxConfigurableAtWorldCreation>1</maxConfigurableAtWorldCreation>
<configurationListOrderPriority>900</configurationListOrderPriority>
<dropPodActive>ActiveDropPodMechanoid</dropPodActive>
<dropPodIncoming>DropPodIncomingMechanoidRapid</dropPodIncoming>
<disallowedRaidAgeRestrictions>
<li MayRequire="Ludeon.RimWorld.Biotech">Children</li>
</disallowedRaidAgeRestrictions>
</FactionDef>
</Defs>

View File

@@ -914,91 +914,6 @@
</stages>
</HediffDef>
<!-- 背景故事重置 -->
<ThingDef ParentName="BodyPartProstheticMakeableBase">
<defName>Wula_BackstoryRegeneratorImplant</defName>
<label>合成人人格数据包</label>
<description>从乌拉帝国上行链路下载的数据包,内含随机的人格数据,机械乌拉在使用后会改变其人格,这会重置它禁止的工作,但是不会重设其热情和特质。\n\n新的人格有可能和旧人格一模一样</description>
<thingClass>ThingWithComps</thingClass>
<graphicData>
<texPath>Wula/Item/WULA_Syhth_Trainer</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<statBases>
<MarketValue>1500</MarketValue>
<Mass>0.1</Mass>
</statBases>
<recipeMaker>
<researchPrerequisites Inherit="False">
<li>WULA_New_Synth_Skill_2_Technology</li>
</researchPrerequisites>
<researchPrerequisite Inherit="False"/>
<skillRequirements>
<Crafting>8</Crafting>
</skillRequirements>
<recipeUsers Inherit="False">
<li>WULA_Synth_Server</li>
</recipeUsers>
</recipeMaker>
<costList>
<Steel>50</Steel>
<ComponentSpacer>1</ComponentSpacer>
<WULA_Charge_Cube>1</WULA_Charge_Cube>
</costList>
<comps>
<li Class="CompProperties_Usable">
<compClass>CompUsableImplant</compClass>
<useJob>UseItem</useJob>
<useLabel>使用 {0_label}</useLabel>
</li>
<li Class="CompProperties_UseEffectInstallImplant">
<hediffDef>Wula_RegenerateBackstory</hediffDef>
<bodyPart>Brain</bodyPart>
</li>
<li Class="CompProperties_UseEffectDestroySelf" />
</comps>
</ThingDef>
<HediffDef ParentName="ImplantHediffBase">
<defName>Wula_RegenerateBackstory</defName>
<label>backstory regenerator</label>
<labelNoun>a backstory regenerator</labelNoun>
<description>A backstory regenerator is installed.</description>
<spawnThingOnRemoved>Wula_BackstoryRegeneratorImplant</spawnThingOnRemoved>
<comps>
<li Class="WulaFallenEmpire.HediffCompProperties_RegenerateBackstory">
<spawnCategories>
<li>Wula_Backstory_Categories</li>
</spawnCategories>
<regenerateChildhood>false</regenerateChildhood>
</li>
</comps>
</HediffDef>
<!-- <RecipeDef ParentName="SurgeryInstallImplantBase">
<defName>InstallWulaBackstoryRegenerator</defName>
<label>install backstory regenerator</label>
<description>Installs a backstory regenerator.</description>
<jobString>Installing backstory regenerator.</jobString>
<ingredients>
<li>
<filter>
<thingDefs>
<li>Wula_BackstoryRegeneratorImplant</li>
</thingDefs>
</filter>
<count>1</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>Wula_BackstoryRegeneratorImplant</li>
</thingDefs>
</fixedIngredientFilter>
<appliedOnFixedBodyParts>
<li>Brain</li>
</appliedOnFixedBodyParts>
<addsHediff>Wula_RegenerateBackstory</addsHediff>
</RecipeDef> -->
<!-- 修复器 -->
<ThingDef ParentName="MechSerumBase">
<defName>WULA_MechRepairKit</defName>

View File

@@ -5,7 +5,7 @@
<defName>Wula_Synth</defName>
<label>合成人</label>
<description>乌拉帝国制式合成人,拥有一部分机械体的特性——她们无法被点燃、不会中毒、免疫大量疾病、不会抱怨温度,但是无法自我修复,并且需要获取能量以维持机体运转。</description>
<hediffClass>HediffWithComps</hediffClass>
<hediffClass>Hediff_High</hediffClass>
<everCurableByItem>false</everCurableByItem>
<duplicationAllowed>false</duplicationAllowed>
<keepOnBodyPartRestoration>True</keepOnBodyPartRestoration>

View File

@@ -152,6 +152,9 @@
<shaderType>CutoutWithOverlay</shaderType>
<graphicClass>Graphic_Multi</graphicClass>
<drawSize>5</drawSize>
<shadowData>
<volume>(0.8, 1.6, 0.65)</volume>
</shadowData>
</bodyGraphicData>
</li>
</lifeStages>
@@ -180,6 +183,9 @@
<shaderType>CutoutWithOverlay</shaderType>
<graphicClass>Graphic_Multi</graphicClass>
<drawSize>5</drawSize>
<shadowData>
<volume>(0.8, 1.6, 0.65)</volume>
</shadowData>
</bodyGraphicData>
</li>
</lifeStages>

View File

@@ -885,4 +885,65 @@
</li>
</comps>
</ThingDef>
<!-- 背景故事重置 -->
<ThingDef ParentName="BodyPartProstheticMakeableBase">
<defName>Wula_BackstoryRegeneratorImplant</defName>
<label>合成人人格数据包</label>
<description>从乌拉帝国上行链路下载的数据包,内含随机的人格数据,机械乌拉在使用后会改变其人格,这会重置它禁止的工作,但是不会重设其热情和特质。\n\n新的人格有可能和旧人格一模一样且必须保存游戏后重新加载才能起效</description>
<thingClass>ThingWithComps</thingClass>
<graphicData>
<texPath>Wula/Item/WULA_Syhth_Trainer</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<statBases>
<MarketValue>1500</MarketValue>
<Mass>0.1</Mass>
</statBases>
<recipeMaker>
<researchPrerequisites Inherit="False">
<li>WULA_New_Synth_Skill_2_Technology</li>
</researchPrerequisites>
<researchPrerequisite Inherit="False"/>
<skillRequirements>
<Crafting>8</Crafting>
</skillRequirements>
<recipeUsers Inherit="False">
<li>WULA_Synth_Server</li>
</recipeUsers>
</recipeMaker>
<costList>
<Steel>50</Steel>
<ComponentSpacer>1</ComponentSpacer>
<WULA_Charge_Cube>1</WULA_Charge_Cube>
</costList>
<comps>
<li Class="CompProperties_Usable">
<compClass>CompUsableImplant</compClass>
<useJob>UseItem</useJob>
<useLabel>使用 {0_label}</useLabel>
</li>
<li Class="CompProperties_UseEffectInstallImplant">
<hediffDef>Wula_RegenerateBackstory</hediffDef>
<bodyPart>Brain</bodyPart>
</li>
<li Class="CompProperties_UseEffectDestroySelf" />
</comps>
</ThingDef>
<HediffDef ParentName="ImplantHediffBase">
<defName>Wula_RegenerateBackstory</defName>
<label>backstory regenerator</label>
<labelNoun>a backstory regenerator</labelNoun>
<description>A backstory regenerator is installed.</description>
<spawnThingOnRemoved>Wula_BackstoryRegeneratorImplant</spawnThingOnRemoved>
<comps>
<li Class="WulaFallenEmpire.HediffCompProperties_RegenerateBackstory">
<spawnCategories>
<li>Wula_Backstory_Categories</li>
</spawnCategories>
<regenerateChildhood>false</regenerateChildhood>
</li>
</comps>
</HediffDef>
</Defs>

View File

@@ -72,13 +72,16 @@
<damageData>
<enabled>false</enabled>
</damageData>
<shadowData>
<volume>(0.75, 0.75, 0.5)</volume>
</shadowData>
</graphicData>
<constructEffect>ConstructMetal</constructEffect>
<costList>
<Steel>50</Steel>
</costList>
<altitudeLayer>Building</altitudeLayer>
<castEdgeShadows>true</castEdgeShadows>
<castEdgeShadows>false</castEdgeShadows>
<fillPercent>0.5</fillPercent>
<useHitPoints>True</useHitPoints>
<statBases>
@@ -147,8 +150,10 @@
<damageData>
<enabled>false</enabled>
</damageData>
<shadowData>
<volume>(0.75, 0.75, 0.5)</volume>
</shadowData>
</graphicData>
<castEdgeShadows>true</castEdgeShadows>
<constructEffect>ConstructMetal</constructEffect>
<costList>
<Steel>80</Steel>
@@ -217,11 +222,14 @@
<damageData>
<enabled>false</enabled>
</damageData>
<shadowData>
<volume>(1.65, 1.65, 0.85)</volume>
<offset>(0, 0, -0.2)</offset>
</shadowData>
</graphicData>
<altitudeLayer>Building</altitudeLayer>
<passability>PassThroughOnly</passability>
<castEdgeShadows>true</castEdgeShadows>
<staticSunShadowHeight>0.35</staticSunShadowHeight>
<castEdgeShadows>false</castEdgeShadows>
<fillPercent>0.5</fillPercent>
<canOverlapZones>false</canOverlapZones>
<pathCost>42</pathCost>
@@ -260,7 +268,6 @@
<maxSimultaneous>1</maxSimultaneous>
</li>
</comps>
<designationHotKey>Misc6</designationHotKey>
<placeWorkers>
<li>PlaceWorker_ShowFacilitiesConnections</li>
</placeWorkers>
@@ -281,7 +288,13 @@
<damageData>
<enabled>false</enabled>
</damageData>
<shadowData>
<volume>(0.8, 1.5, 0.9)</volume>
<!-- <offset>(-0.05, 0, 0.35)</offset> -->
</shadowData>
</graphicData>
<staticSunShadowHeight Inherit="False" IsNull="True" />
<castEdgeShadows>False</castEdgeShadows>
<statBases>
<Comfort>0.75</Comfort>
<MaxHitPoints>140</MaxHitPoints>
@@ -296,11 +309,8 @@
<ComponentIndustrial>1</ComponentIndustrial>
<WULA_Charge_Cube>1</WULA_Charge_Cube>
</costList>
<designationHotKey>Misc2</designationHotKey>
<uiOrder>2010</uiOrder>
<castEdgeShadows>true</castEdgeShadows>
<fillPercent>0.5</fillPercent>
<staticSunShadowHeight>0</staticSunShadowHeight>
<designationCategory>WULA_Buildings</designationCategory>
<researchPrerequisites Inherit="False">
<li>WULA_Base_Technology</li>
@@ -346,7 +356,6 @@
<drawSize>(3,4)</drawSize>
</graphicData>
<size>(1,2)</size>
<designationHotKey>Misc1</designationHotKey>
</ThingDef>
<!-- 机械工厂 -->
@@ -362,7 +371,6 @@
<passability>PassThroughOnly</passability>
<fillPercent>0.5</fillPercent>
<hasInteractionCell>true</hasInteractionCell>
<castEdgeShadows>true</castEdgeShadows>
<pathCost>42</pathCost>
<surfaceType>Item</surfaceType>
<inspectorTabs>
@@ -379,7 +387,12 @@
<texPath>Wula/Building/WULA_Heavy_War_Machine_Productor</texPath>
<graphicClass>Graphic_Multi</graphicClass>
<drawSize>(4, 4)</drawSize>
<shadowData>
<volume>(2.8, 2.8, 2.1)</volume>
<!-- <offset>(-0.05, 0, 0.35)</offset> -->
</shadowData>
</graphicData>
<castEdgeShadows>False</castEdgeShadows>
<interactionCellOffset>(1,0,3)</interactionCellOffset>
<statBases>
<MaxHitPoints>1250</MaxHitPoints>
@@ -559,7 +572,7 @@
</ThingDef>
<!-- 联络台 -->
<ThingDef ParentName="BuildingBase">
<ThingDef ParentName="BuildingBase">
<defName>WULA_Communicator_Station</defName>
<label>乌拉帝国通讯站</label>
<description>乌拉帝国内部用于联系的通讯站,可以联系到乌拉帝国的各大派系。</description>
@@ -569,6 +582,9 @@
<graphicClass>Graphic_Multi</graphicClass>
<shaderType>TransparentPostLight</shaderType>
<drawSize>(1,1)</drawSize>
<shadowData>
<volume>(0.25, 0.25, 0.25)</volume>
</shadowData>
</graphicData>
<statBases>
<MaxHitPoints>250</MaxHitPoints>
@@ -618,7 +634,7 @@
<rect>(0.3,0.3,1.4,1.4)</rect>
</damageData>
<shadowData>
<volume>(1.5,0.35,1.4)</volume>
<volume>(0.5,0.35,0.75)</volume>
<offset>(0,0,-0.05)</offset>
</shadowData>
</graphicData>
@@ -739,6 +755,10 @@
<texPath>Wula/Building/WULA_Synth_Maintainer_south</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>(3, 3)</drawSize>
<shadowData>
<volume>(1.5, 1.5, 1.7)</volume>
<!-- <offset>(-0.05, 0, 0.35)</offset> -->
</shadowData>
</graphicData>
<drawerType>RealtimeOnly</drawerType>
<drawGUIOverlay>true</drawGUIOverlay>

View File

@@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BaseHumanMakeableGun">
<defName>WULA_RW_MeltBeam_Cannon_Example</defName>
<label>铋晶Melt射线炮 (示例)</label>
<description>一个使用Verb_ShootMeltBeam的示例武器。它会扫射出两条弯曲的能量光束并造成范围爆炸。</description>
<techLevel>Ultra</techLevel>
<graphicData>
<texPath>Wula/Weapon/WULA_RW_DM_Cannon</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>1.5</drawSize>
</graphicData>
<weaponTags>
<li>Wula_Ranged_Weapon_T4</li>
</weaponTags>
<uiIconScale>0.8</uiIconScale>
<soundInteract>Interact_ChargeRifle</soundInteract>
<recipeMaker>
<recipeUsers Inherit="False">
<li>WULA_Cube_Productor_Energy</li>
</recipeUsers>
<researchPrerequisite>WULA_Synth_Weapon_4_DM_Base_Technology</researchPrerequisite>
<unfinishedThingDef>UnfinishedWeapon</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">
<Steel>500</Steel>
<Plasteel>300</Plasteel>
<WULA_Dark_Matter_Item>6</WULA_Dark_Matter_Item>
</costList>
<statBases>
<WorkToMake>50000</WorkToMake>
<Mass>10</Mass>
<AccuracyTouch>0.6</AccuracyTouch>
<AccuracyShort>0.6</AccuracyShort>
<AccuracyMedium>0.6</AccuracyMedium>
<AccuracyLong>0.6</AccuracyLong>
<RangedWeapon_Cooldown>3</RangedWeapon_Cooldown>
</statBases>
<verbs>
<li Class="WulaFallenEmpire.VerbPropertiesExplosiveBeam">
<verbClass>WulaFallenEmpire.Verb_ShootMeltBeam</verbClass>
<!-- 基础射线参数 -->
<hasStandardCommand>true</hasStandardCommand>
<warmupTime>1.5</warmupTime>
<range>25</range>
<burstShotCount>20</burstShotCount>
<ticksBetweenBurstShots>5</ticksBetweenBurstShots>
<beamDamageDef>Wula_Dark_Matter_Beam</beamDamageDef>
<!-- 核心光束塑形参数 -->
<beamFullWidthRange>12</beamFullWidthRange> <!-- 光束达到最大宽度的距离 -->
<beamWidth>5</beamWidth> <!-- 光束的最大宽度 -->
<beamMaxDeviation>0.8</beamMaxDeviation> <!-- 光束路径的随机偏移量 -->
<beamCurvature>0.7</beamCurvature> <!-- 光束的弯曲程度 -->
<beamStartOffset>0.5</beamStartOffset> <!-- 光束起始点距离发射者的偏移 -->
<!-- 视觉和音效 -->
<muzzleFlashScale>0</muzzleFlashScale>
<soundCastBeam>BeamGraser_Shooting</soundCastBeam>
<beamGroundFleckDef>Fleck_BeamBurn</beamGroundFleckDef>
<beamFleckChancePerTick>0.32</beamFleckChancePerTick>
<beamMoteDef>Mote_Wula_Dark_Matter_Beam</beamMoteDef>
<beamEndEffecterDef>GraserBeam_End</beamEndEffecterDef>
<!-- 火焰效果 -->
<beamSetsGroundOnFire>true</beamSetsGroundOnFire> <!-- 光束是否点燃地面 -->
<beamChanceToStartFire>0.5</beamChanceToStartFire>
<beamChanceToAttachFire>0.5</beamChanceToAttachFire>
<beamFireSizeRange>0.2~0.4</beamFireSizeRange> <!-- 火焰大小范围 -->
<!-- 其他射线属性 -->
<beamHitsNeighborCells>true</beamHitsNeighborCells>
<stopBurstWithoutLos>false</stopBurstWithoutLos> <!-- 即使失去视野也继续扫射 -->
<!-- 攻击目标设置 -->
<targetParams>
<canTargetLocations>true</canTargetLocations>
</targetParams>
<!-- 爆炸参数 -->
<enableExplosion>true</enableExplosion>
<explosionShotInterval>3</explosionShotInterval> <!-- 每3次射击判定一次爆炸 -->
<explosionRadius>2.5</explosionRadius>
<explosionDamageDef>Wula_Dark_Matter_Flame</explosionDamageDef>
<explosionDamage>20</explosionDamage>
<explosionSound>Explosion_Bomb</explosionSound>
<chanceToStartFire>0.6</chanceToStartFire>
<screenShakeFactor>0.3</screenShakeFactor> <!-- 爆炸时的屏幕震动 -->
</li>
</verbs>
<tradeability>None</tradeability>
<thingSetMakerTags>
<li>RewardStandardQualitySuper</li>
</thingSetMakerTags>
</ThingDef>
</Defs>

View File

@@ -1,18 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<!-- 普通好感初始事件 -->
<WulaFallenEmpire.EventDef>
<defName>Wula_UI_FE_Spiritualist_1</defName>
<label>乌拉帝国 大教堂</label>
<portraitPath>Wula/Events/Portraits/WULA_FE_Spiritualist_3</portraitPath>
<characterName>帝国修女</characterName>
<descriptions>
<li><![CDATA[这里是乌拉帝国教会,很不高兴听你们废话。请问有何贵干?
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[好,好,你们是来聆听布道的,还是来谈生意的?
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[以主之名,我们当为边缘世界的愚昧众生带去教化——但是在那之前,这个蛮荒之地还有很多很多血要流。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li>高好感度问候</li>
</descriptions>
<immediateEffects>
<li>
@@ -24,40 +18,25 @@
<factionDef>Wula_FE_Spiritualist_Faction</factionDef>
<variableName>Wula_FE_Spiritualist_Goodwill</variableName>
</li>
<li Class="WulaFallenEmpire.Effect_SetVariable">
<name>WULA_FE_Spiritualist_Influence</name>
<value>0</value>
<type>Int</type>
</li>
</effects>
</li>
</immediateEffects>
<options>
<li>
<label>你们是谁</label>
<label>你们能再详细地说说你们自己吗</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
<li Class="WulaFallenEmpire.Effect_OpenCustomUI">
<defName>Wula_UI_FE_Spiritualist_10</defName>
</li>
</effects>
</li>
</optionEffects>
</li>
<li>
<label>你们有什么任务可以给我们吗?</label>
<optionEffects>
<li>
<effects>
<!-- <li Class="WulaFallenEmpire.Effect_AddQuest">
<quest>Wula_FE_Quest_Attack_Mercenary</quest>
</li> -->
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>我们有一个请求</label>
<optionEffects>
<li>
<effects>
@@ -78,19 +57,13 @@
</li>
</options>
</WulaFallenEmpire.EventDef>
<!-- 高好感初始事件 -->
<WulaFallenEmpire.EventDef>
<defName>Wula_UI_FE_Spiritualist_2</defName>
<label>乌拉帝国 大教堂</label>
<portraitPath>Wula/Events/Portraits/WULA_FE_Spiritualist_3</portraitPath>
<characterName>帝国修女</characterName>
<descriptions>
<li><![CDATA[虽然你们不是我主拥趸,但是破格招待一下你们还是可以的。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[愿吾主也庇佑你们,就像祂庇佑乌拉星人一样。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[我们被选中,守护乌拉星人的应许之地。我们已经执行了这条戒律千百年,今后也是如此。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li>中好感度问候</li>
</descriptions>
<immediateEffects>
<li>
@@ -103,21 +76,19 @@
<factionDef>Wula_FE_Spiritualist_Faction</factionDef>
<variableName>Wula_FE_Spiritualist_Goodwill</variableName>
</li>
<li Class="WulaFallenEmpire.Effect_SetVariable">
<name>WULA_FE_Spiritualist_Influence</name>
<value>0</value>
<type>Int</type>
</li>
</effects>
</li>
</immediateEffects>
<options>
<li>
<label>你们是谁</label>
<label>你们能再详细地说说你们自己吗</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
<li Class="WulaFallenEmpire.Effect_OpenCustomUI">
<defName>Wula_UI_FE_Spiritualist_10</defName>
</li>
</effects>
</li>
</optionEffects>
@@ -144,19 +115,13 @@
</li>
</options>
</WulaFallenEmpire.EventDef>
<!-- 低好感初始事件 -->
<WulaFallenEmpire.EventDef>
<defName>Wula_UI_FE_Spiritualist_3</defName>
<label>乌拉帝国 大教堂</label>
<portraitPath>Wula/Events/Portraits/WULA_FE_Spiritualist_2</portraitPath>
<characterName>帝国修女</characterName>
<descriptions>
<li><![CDATA[你们会为无知和傲慢付出代价的,野蛮人。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[·····明明只是一群臭鱼烂虾居然敢对帝国教会不敬真该把你们这群无信者折磨宰杀剥皮缝制沙发肉丢给沼泽猎犬头颅挂在枯树上诅咒你们的灵魂迷失在至高天中烂在无人知晓的角落变成虚境生物的脚底烂泥。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[你们的玷污行为很快就会遭到惩戒。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li>低好感度问候</li>
</descriptions>
<immediateEffects>
<li>
@@ -169,11 +134,6 @@
<factionDef>Wula_FE_Spiritualist_Faction</factionDef>
<variableName>Wula_FE_Spiritualist_Goodwill</variableName>
</li>
<li Class="WulaFallenEmpire.Effect_SetVariable">
<name>WULA_FE_Spiritualist_Influence</name>
<value>0</value>
<type>Int</type>
</li>
</effects>
</li>
</immediateEffects>
@@ -185,6 +145,18 @@
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
<!-- 在低好感任务随机选择一个 -->
<randomlistEffects>
<li Class="WulaFallenEmpire.Effect_OpenCustomUI">
<defName>Wula_UI_FE_Spiritualist_20</defName>
</li>
<!-- <li Class="WulaFallenEmpire.Effect_OpenCustomUI">
<defName>Wula_UI_FE_Spiritualist_21</defName>
</li>
<li Class="WulaFallenEmpire.Effect_OpenCustomUI">
<defName>Wula_UI_FE_Spiritualist_22</defName>
</li> -->
</randomlistEffects>
</li>
</optionEffects>
</li>
@@ -222,19 +194,64 @@
</li>
</options>
</WulaFallenEmpire.EventDef>
<WulaFallenEmpire.EventDef>
<defName>Wula_UI_FE_Spiritualist_4</defName>
<label>第一次联络</label>
<portraitPath>Wula/Events/Portraits/WULA_FE_Spiritualist_1</portraitPath>
<characterName>帝国修女</characterName>
<descriptions>
<li>第一次联络问候</li>
</descriptions>
<immediateEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_ModifyVariable">
<name>Wula_FE_Spiritualist_First_Contant</name>
<operation>Add</operation>
<value>1</value>
</li>
</effects>
</li>
</immediateEffects>
<options>
<li>
<label>好的,我们尊重你们的信仰,也请你们尊重我们的殖民地</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>你们信仰的主该不是什么飞天大茄子吧?</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
<li Class="WulaFallenEmpire.Effect_ChangeFactionRelation">
<faction>Wula_FE_Spiritualist_Faction</faction>
<goodwillChange>-50</goodwillChange>
</li>
<li Class="WulaFallenEmpire.Effect_ShowMessage">
<message>你的轻佻发言惹得乌拉帝国 大教堂非常的不快,她们对你的第一印象大幅度降低了!</message>
<messageTypeDef>NegativeEvent</messageTypeDef>
</li>
</effects>
</li>
</optionEffects>
</li>
</options>
</WulaFallenEmpire.EventDef>
<!-- 普通好感初始事件 -->
<WulaFallenEmpire.EventDef>
<defName>Wula_UI_FE_Spiritualist_10</defName>
<label>乌拉帝国 大教堂</label>
<portraitPath>Wula/Events/Portraits/WULA_FE_Spiritualist_1</portraitPath>
<characterName>帝国修女</characterName>
<descriptions>
<li>我们是乌拉帝国国教教会,在帝国皇室没落以前,我们曾是每任皇帝的左膀右臂,负责维护</li>
<li><![CDATA[好,好,你们是来聆听布道的,还是来谈生意的?
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[以主之名,我们当为边缘世界的愚昧众生带去教化——但是在那之前,这个蛮荒之地还有很多很多血要流。
<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li>好吧。我们来自乌拉帝国国教教会,也称乌拉帝国 大教堂,而在边缘世界活动的我们则是其中的一个小分支。在帝国皇室没落以前,国教曾是每任皇帝的左膀右臂,负责维护乌拉帝国和皇室的至上威权,并将祂的化身——也就是皇帝——的福音在银河系中传播。\n\n然而我们遭到了无信者的背叛她们自诩进步派否定我主和皇室与生俱来的正确性挑起了一场撕裂帝国的内战。经过护教军的与其的万古长战她们已经被逼至绝境我们也在着手于恢复昔日荣光并将福音再次播撒于星海间。</li>
</descriptions>
<immediateEffects>
<li>
@@ -246,50 +263,12 @@
<factionDef>Wula_FE_Spiritualist_Faction</factionDef>
<variableName>Wula_FE_Spiritualist_Goodwill</variableName>
</li>
<li Class="WulaFallenEmpire.Effect_SetVariable">
<name>WULA_FE_Spiritualist_Influence</name>
<value>0</value>
<type>Int</type>
</li>
</effects>
</li>
</immediateEffects>
<options>
<li>
<label>你们是谁?</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>你们有什么任务可以给我们吗?</label>
<optionEffects>
<li>
<effects>
<!-- <li Class="WulaFallenEmpire.Effect_AddQuest">
<quest>Wula_FE_Quest_Attack_Mercenary</quest>
</li> -->
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>我们有一个请求</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>换个接线员</label>
<label>好的,我们大概了解了</label>
<optionEffects>
<li>
<effects>
@@ -302,39 +281,18 @@
</WulaFallenEmpire.EventDef>
<WulaFallenEmpire.EventDef>
<defName>Wula_UI_FE_Spiritualist_11</defName>
<defName>Wula_UI_FE_Spiritualist_20</defName>
<label>乌拉帝国 大教堂</label>
<portraitPath>Wula/Events/Portraits/WULA_FE_Spiritualist_1</portraitPath>
<portraitPath>Wula/Events/Portraits/WULA_FE_Spiritualist_3</portraitPath>
<characterName>帝国修女</characterName>
<descriptions>
<li><![CDATA[这里是乌拉帝国教会,请问有何贵干?\n\n<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[你们是来聆听布道的,还是来谈生意的?\n\n<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<li><![CDATA[以主之名,我们当为边缘世界的愚昧众生带去教化。\n\n<color=#ff8c00><b>当前在乌拉帝国大教堂的影响力: {WULA_FE_Spiritualist_Influence}</b></color>]]></li>
<!-- <li>·····明明只是一群臭鱼烂虾居然敢对帝国教会刀剑相向真该把你们这群无信者折磨宰杀剥皮缝制沙发肉丢给沼泽猎犬头颅挂在枯树上诅咒你们的灵魂迷失在至高天中烂在无人知晓的角落变成虚境生物的脚底烂泥</li> -->
<li>低好感度任务介绍1。</li>
</descriptions>
<immediateEffects>
<li>
<effects>
<!-- 检测dlc开启情况以决定启动哪些系统 -->
<li Class="WulaFallenEmpire.Effect_ClearVariable">
<name>Wula_FE_Spiritualist_Goodwill</name>
</li>
<li Class="WulaFallenEmpire.Effect_CheckFactionGoodwill">
<factionDef>Wula_FE_Spiritualist_Faction</factionDef>
<variableName>Wula_FE_Spiritualist_Goodwill</variableName>
</li>
<li Class="WulaFallenEmpire.Effect_SetVariable">
<name>WULA_FE_Spiritualist_Influence</name>
<value>0</value>
<type>Int</type>
</li>
</effects>
</li>
</immediateEffects>
<options>
<li>
<label>你们是谁?</label>
<label>我们接受</label>
<optionEffects>
<li>
<effects>
@@ -344,27 +302,7 @@
</optionEffects>
</li>
<li>
<label>你们有什么任务可以给我们吗?</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>我们有一个请求</label>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
<li>
<label>换个接线员</label>
<label>不行,我们改主意了</label>
<optionEffects>
<li>
<effects>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<!-- 大教堂 -->
<FactionDef ParentName="FactionBase">
<defName>Wula_FE_Spiritualist_Faction</defName>
<label>乌拉帝国 大教堂</label>
@@ -8,24 +7,15 @@
<basicMemberKind>RealWula_PawnKind</basicMemberKind>
<pawnSingular>乌拉星人</pawnSingular>
<pawnsPlural>乌拉星人</pawnsPlural>
<settlementGenerationWeight>1</settlementGenerationWeight>
<categoryTag>Wula_FE_Spiritualist_FactionTag</categoryTag>
<requiredCountAtGameStart>1</requiredCountAtGameStart>
<factionNameMaker>NamerFaction_Wula_FE_Spiritualist</factionNameMaker>
<factionIconPath>Wula/World/WorldObjects/Expanding/Wula_FE_Faction</factionIconPath>
<displayInFactionSelection>false</displayInFactionSelection>
<!-- <settlementGenerationWeight>1</settlementGenerationWeight> -->
<requiredCountAtGameStart>1</requiredCountAtGameStart>
<categoryTag>Wula_FE_Spiritualist_Faction</categoryTag>
<canSiege>false</canSiege>
<canStageAttacks>true</canStageAttacks>
<leaderTitle>星域主教</leaderTitle>
<leaderForceGenerateNewPawn>true</leaderForceGenerateNewPawn>
<factionIconPath>Wula/World/WorldObjects/Expanding/Wula_FE_Faction</factionIconPath>
<colorSpectrum>
<li>(0.6, 0.5, 0.9)</li>
</colorSpectrum>
<factionNameMaker>NamerFaction_Wula_FE_Spiritualist</factionNameMaker>
<settlementNameMaker>NamerSettlement_Wula_FE_Spiritualist</settlementNameMaker>
<allowedCultures><li>Sophian</li></allowedCultures>
<arrivalLayerWhitelist>
<li>Surface</li>
<!-- <li MayRequire="Ludeon.RimWorld.Odyssey">Orbit</li> -->
</arrivalLayerWhitelist>
<backstoryCategories>
<li>Wula_Backstory_Categories_For_RealWula</li>
</backstoryCategories>
@@ -52,6 +42,36 @@
<li>WULA_Awakened_Synth</li>
</permanentEnemyToEveryoneExcept>
<techLevel>Archotech</techLevel>
<arrivalLayerWhitelist>
<li>Surface</li>
<!-- <li MayRequire="Ludeon.RimWorld.Odyssey">Orbit</li> -->
</arrivalLayerWhitelist>
<colorSpectrum>
<li>(0.6, 0.5, 0.9)</li>
</colorSpectrum>
<raidCommonalityFromPointsCurve>
<points>
<li>(300, 0)</li>
<li>(700, 1)</li>
<li>(1400, 1.8)</li>
<li>(2800, 2.2)</li>
<li>(4000, 2.6)</li>
</points>
</raidCommonalityFromPointsCurve>
<!-- <raidLootMaker>MechanoidRaidLootMaker</raidLootMaker> -->
<raidLootValueFromPointsCurve>
<points>
<li>(35, 8)</li>
<li>(100, 60)</li>
<li>(1000, 250)</li>
<li>(2000, 400)</li>
<li>(4000, 500)</li>
</points>
</raidLootValueFromPointsCurve>
<humanlikeFaction>true</humanlikeFaction>
<hidden>true</hidden>
<!-- <autoFlee>false</autoFlee> -->
<canUseAvoidGrid>false</canUseAvoidGrid>
<apparelStuffFilter>
<stuffCategoriesToAllow>
<li>Metallic</li>
@@ -61,83 +81,34 @@
<li>DevilstrandCloth</li>
</disallowedThingDefs>
</apparelStuffFilter>
<allowedArrivalTemperatureRange>-40~45</allowedArrivalTemperatureRange>
<settlementTexturePath>World/WorldObjects/DefaultSettlement</settlementTexturePath>
<colorSpectrum>
<li>(0.85, 0.85, 0.75)</li>
</colorSpectrum>
<fixedLeaderKinds>
<li>Wula_FE_Spiritualist_Leader</li>
</fixedLeaderKinds>
<baseTraderKinds>
<li>Wula_FE_Spiritualist_Faction_TraderKind</li>
</baseTraderKinds>
<raidCommonalityFromPointsCurve>
<points>
<li>(0, 1)</li> <!--Constant 1 at all points levels-->
</points>
</raidCommonalityFromPointsCurve>
<raidLootMaker>EmpireRaidLootMaker</raidLootMaker>
<earliestRaidDays>18</earliestRaidDays>
<permanentEnemy>true</permanentEnemy>
<hostileToFactionlessHumanlikes>true</hostileToFactionlessHumanlikes>
<maxPawnCostPerTotalPointsCurve>
<points>
<li>(500, 100)</li> <!-- Can always use relatively strong pawns, because empire doesn't really have weak ones -->
<li>(1000, 150)</li>
<li>(2000, 250)</li>
<li>(2001, 10000)</li>
<li>(400,200)</li>
<li>(900,300)</li>
<li>(100000,10000)</li>
</points>
</maxPawnCostPerTotalPointsCurve>
<pawnGroupMakers>
<li>
<!-- Base defense, mainly ranged with melee mix-ins -->
<kindDef>Settlement</kindDef>
<kindDef>Combat</kindDef>
<commonality>50</commonality>
<options>
<Wula_FE_Spiritualist_Pawn_1>10</Wula_FE_Spiritualist_Pawn_1>
<Wula_FE_Spiritualist_Pawn_2>3</Wula_FE_Spiritualist_Pawn_2>
<Wula_FE_Spiritualist_Pawn_3>3</Wula_FE_Spiritualist_Pawn_3>
<Wula_FE_Spiritualist_Pawn_4>1</Wula_FE_Spiritualist_Pawn_4>
</options>
</li>
<li>
<!-- Peaceful -->
<kindDef>Peaceful</kindDef>
<options>
<Wula_FE_Spiritualist_Pawn_1>10</Wula_FE_Spiritualist_Pawn_1>
<Wula_FE_Spiritualist_Pawn_2>3</Wula_FE_Spiritualist_Pawn_2>
<Wula_FE_Spiritualist_Pawn_3>3</Wula_FE_Spiritualist_Pawn_3>
<Wula_FE_Spiritualist_Pawn_4>1</Wula_FE_Spiritualist_Pawn_4>
</options>
</li>
<li MayRequire="Ludeon.RimWorld.Ideology">
<kindDef>Miners</kindDef>
<commonality>1</commonality>
<options>
<Mech_WULA_Cat_Constructor>1</Mech_WULA_Cat_Constructor>
</options>
</li>
<li MayRequire="Ludeon.RimWorld.Ideology">
<kindDef>Hunters</kindDef>
<commonality>1</commonality>
<options>
<Mech_WULA_Cat_Assault>1</Mech_WULA_Cat_Assault>
</options>
</li>
<li MayRequire="Ludeon.RimWorld.Ideology">
<kindDef>Loggers</kindDef>
<commonality>1</commonality>
<options>
<Mech_WULA_Cat>1</Mech_WULA_Cat>
</options>
</li>
<li MayRequire="Ludeon.RimWorld.Ideology">
<kindDef>Farmers</kindDef>
<commonality>1</commonality>
<options>
<Mech_WULA_Cat>1</Mech_WULA_Cat>
<Mech_WULA_Cat_Assault>60</Mech_WULA_Cat_Assault>
<Mech_WULA_Cat_Constructor>30</Mech_WULA_Cat_Constructor>
<Mech_WULA_Cat_Fire>20</Mech_WULA_Cat_Fire>
<Mech_WULA_Cat_EMP>20</Mech_WULA_Cat_EMP>
</options>
</li>
</pawnGroupMakers>
<settlementTexturePath>World/WorldObjects/DefaultSettlement</settlementTexturePath>
<allowedArrivalTemperatureRange>-100~200</allowedArrivalTemperatureRange>
<maxConfigurableAtWorldCreation>1</maxConfigurableAtWorldCreation>
<configurationListOrderPriority>70</configurationListOrderPriority>
<configurationListOrderPriority>900</configurationListOrderPriority>
<dropPodActive>ActiveDropPodMechanoid</dropPodActive>
<dropPodIncoming>DropPodIncomingMechanoidRapid</dropPodIncoming>
<disallowedRaidAgeRestrictions>
<li MayRequire="Ludeon.RimWorld.Biotech">Children</li>
</disallowedRaidAgeRestrictions>

View File

@@ -9,6 +9,55 @@
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Base_Technology1</defName>
<label>乌拉帝国大教堂科技阶段1</label>
<description>这个科技没有任何用处,但是有一部分科技依托于此科技</description>
<baseCost>8500000</baseCost>
<researchViewX>0.00</researchViewX>
<researchViewY>3.00</researchViewY>
<techprintCount>1</techprintCount>
<techprintCommonality>3</techprintCommonality>
<techprintMarketValue>10000</techprintMarketValue>
<heldByFactionCategoryTags>
<li>Wula_FE_Spiritualist_FactionTag</li>
</heldByFactionCategoryTags>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Base_Technology2</defName>
<label>乌拉帝国大教堂科技阶段2</label>
<description>这个科技没有任何用处,但是有一部分科技依托于此科技</description>
<baseCost>15000000</baseCost>
<researchViewX>2.50</researchViewX>
<researchViewY>3.00</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology1</li>
</prerequisites>
<techprintCount>1</techprintCount>
<techprintCommonality>3</techprintCommonality>
<techprintMarketValue>10000</techprintMarketValue>
<heldByFactionCategoryTags>
<li>Wula_FE_Spiritualist_FactionTag</li>
</heldByFactionCategoryTags>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Base_Technology3</defName>
<label>乌拉帝国大教堂科技阶段3</label>
<description>这个科技没有任何用处,但是有一部分科技依托于此科技</description>
<baseCost>35000000</baseCost>
<researchViewX>4.50</researchViewX>
<researchViewY>3.00</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology2</li>
</prerequisites>
<techprintCount>1</techprintCount>
<techprintCommonality>3</techprintCommonality>
<techprintMarketValue>10000</techprintMarketValue>
<heldByFactionCategoryTags>
<li>Wula_FE_Spiritualist_FactionTag</li>
</heldByFactionCategoryTags>
</ResearchProjectDef>
<!-- <ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Base_Technology</defName>
<label>泽洛提炼</label>
<description>若要开启乌拉帝国灵能科技树的大门,掌握基础的泽洛提炼技术是必要的。</description>
@@ -19,23 +68,26 @@
<li>WULA_Dark_Matter_Technology</li>
<li>WULA_Synth_Psi_Technology</li>
</prerequisites>
<!-- <techprintCount>1</techprintCount>
<techprintCount>1</techprintCount>
<techprintCommonality>3</techprintCommonality>
<techprintMarketValue>3000</techprintMarketValue> -->
</ResearchProjectDef>
<techprintMarketValue>10000</techprintMarketValue>
<heldByFactionCategoryTags>
<li>Wula_FE_Spiritualist_FactionTag</li>
</heldByFactionCategoryTags>
</ResearchProjectDef> -->
<!-- 衣服 -->
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Cloth_Technology</defName>
<label>护教军制服</label>
<description>乌拉帝国的国教人员使用的一种轻型装甲相较于制式帝国突击队装甲拥有更强大的区域灵能盾可以抵御射弹和EMP武器的袭击。</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewX>3.50</researchViewX>
<researchViewY>2.00</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology2</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<!-- <ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Cloth2_Technology</defName>
<label>神官制服</label>
<description>乌拉帝国的高阶国教人员所着的华丽衣装,拥有令人瞠目结舌的庞大、坚实的灵能护盾,几乎不可能被外界射弹火力打穿;除此之外还能增强穿戴者的心灵敏感度,提高闪避能力,并降低崩溃风险。</description>
@@ -45,17 +97,17 @@
<prerequisites>
<li>WULA_FE_Spiritualist_Cloth_Technology</li>
</prerequisites>
</ResearchProjectDef>
</ResearchProjectDef> -->
<!-- 加护 -->
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_SwiftHunterBlessing_Technology</defName>
<label>迅捷猎手加护</label>
<description>以乌拉帝国的仪式强化被召选者,使其获得额外的移动速度和瞄准速度。</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewX>1.00</researchViewX>
<researchViewY>1.30</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology1</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
@@ -63,21 +115,10 @@
<label>深渊恐惧加护</label>
<description>以乌拉帝国的仪式强化被召选者,使其获得额外的伤害减免和近战攻击速度。</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewX>1.00</researchViewX>
<researchViewY>0.60</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_InstantJumpdriveBlessing_Technology</defName>
<label>转瞬移型加护</label>
<description>以乌拉帝国的仪式强化被召选者,使其获得短距离的自体传送能力。</description>
<baseCost>12000</baseCost>
<researchViewX>2.50</researchViewX>
<researchViewY>1.30</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology1</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
@@ -85,34 +126,21 @@
<label>思绪泉涌加护</label>
<description>以乌拉帝国的仪式强化被召选者,使其获得自行激发灵感的能力。</description>
<baseCost>12000</baseCost>
<researchViewX>2.50</researchViewX>
<researchViewX>3.50</researchViewX>
<researchViewY>0.60</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
</prerequisites>
</ResearchProjectDef>
<!-- 术式 -->
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Spear_Impale_Technology</defName>
<label>圣枪穿刺术式</label>
<description>这是乌拉星人所创造的最强大的进攻术式,来源于乌拉星人的泰坦和旗舰。这种术式发射的纯净灵能能量能绕过几乎所有防御,在敌人的集群中连续弹跳,瞬间烧穿无信之徒的可悲躯体。</description>
<baseCost>12000</baseCost>
<researchViewX>2.50</researchViewX>
<researchViewY>5.40</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Cotton_Counter_Technology</li>
<li>WULA_FE_Spiritualist_Live_Shelter_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology2</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Cotton_Counter_Technology</defName>
<label>飘絮反制术式</label>
<description>这是乌拉星人在舰船上用于反制敌方飞行器和导弹的特殊术式,核心在于高爆发性高追踪性的输出,通过快速吟唱汇聚的灵能能量使对方迅速失能</description>
<defName>WULA_FE_Spiritualist_InstantJumpdriveBlessing_Technology</defName>
<label>转瞬移型加护</label>
<description>以乌拉帝国的仪式强化被召选者,使其获得短距离的自体传送能力</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewY>4.80</researchViewY>
<researchViewX>5.50</researchViewX>
<researchViewY>0.60</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology3</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
@@ -120,10 +148,10 @@
<label>生灵庇佑术式</label>
<description>这是乌拉星人用于救治伤者的法术,可以使用灵能诱发伤口以非常规的方式快速愈合,并且效果会在友方个体间弹跳。</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewY>5.40</researchViewY>
<researchViewX>1.00</researchViewX>
<researchViewY>4.70</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology1</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
@@ -131,14 +159,36 @@
<label>灰烬焚烧术式</label>
<description>乌拉星人所使用的压制性术式,能够在短时间的吟唱后喷出大量由灵能能量构成的火焰,这种击穿灵魂的火焰可以无视敌人的护甲,点燃敌人的躯体。</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewY>4.20</researchViewY>
<researchViewX>1.00</researchViewX>
<researchViewY>4.10</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology1</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Cotton_Counter_Technology</defName>
<label>飘絮反制术式</label>
<description>这是乌拉星人在舰船上用于反制敌方飞行器和导弹的特殊术式,核心在于高爆发性高追踪性的输出,通过快速吟唱汇聚的灵能能量使对方迅速失能。</description>
<baseCost>12000</baseCost>
<researchViewX>3.50</researchViewX>
<researchViewY>4.10</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology2</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Spear_Impale_Technology</defName>
<label>圣枪穿刺术式</label>
<description>这是乌拉星人所创造的最强大的进攻术式,来源于乌拉星人的泰坦和旗舰。这种术式发射的纯净灵能能量能绕过几乎所有防御,在敌人的集群中连续弹跳,瞬间烧穿无信之徒的可悲躯体。</description>
<baseCost>12000</baseCost>
<researchViewX>5.50</researchViewX>
<researchViewY>4.10</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology3</li>
</prerequisites>
</ResearchProjectDef>
<!-- 机械体 -->
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<!-- <ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_Psi_Titan_Technology</defName>
<label>灵能泰坦</label>
<description>灵能泰坦是效力于乌拉帝国国教的重型灵能机械体,能够在战场上进行跃迁,拥有强大的实力、坚固的灵能盾和繁多的灵能技能,但是机体本身较为脆弱。</description>
@@ -146,20 +196,20 @@
<researchViewX>1.50</researchViewX>
<researchViewY>0.00</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology1</li>
<li>WULA_Machine_Productor_Technology</li>
</prerequisites>
</ResearchProjectDef>
</ResearchProjectDef> -->
<!-- 组件 -->
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
<defName>WULA_FE_Spiritualist_CPU_Psienhance_Technology</defName>
<label>灵能组件</label>
<description>开发能够安装于机械乌拉的生物处理器的特殊改件,强化其与虚境的亲和,增强心灵敏感度。</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewY>3.40</researchViewY>
<researchViewX>5.50</researchViewX>
<researchViewY>5.40</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology3</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
@@ -167,10 +217,10 @@
<label>预知组件</label>
<description>开发能够安装于机械乌拉的生物处理器的特殊改件,能够让其瞬时地预知敌人的动作,以获得射击精度和近战命中率加成。</description>
<baseCost>12000</baseCost>
<researchViewX>1.50</researchViewX>
<researchViewY>2.70</researchViewY>
<researchViewX>3.50</researchViewX>
<researchViewY>5.40</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology2</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="WULA_FE_Spiritualist_techBase">
@@ -178,10 +228,10 @@
<label>魂楔提取器</label>
<description>开发一种特殊插件,会深深地植入俘虏和奴隶的大脑,使其再也无法醒来,并周期性地产生魂楔——年龄越大,凝聚速度越快。</description>
<baseCost>12000</baseCost>
<researchViewX>2.50</researchViewX>
<researchViewY>2.70</researchViewY>
<researchViewX>1.00</researchViewX>
<researchViewY>5.40</researchViewY>
<prerequisites>
<li>WULA_FE_Spiritualist_Base_Technology</li>
<li>WULA_FE_Spiritualist_Base_Technology1</li>
</prerequisites>
</ResearchProjectDef>
</Defs>

View File

@@ -1,108 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BaseHumanMakeableGun">
<defName>WULA_RW_MeltBeam_Cannon_Example</defName>
<label>铋晶Melt射线炮 (示例)</label>
<description>一个使用Verb_ShootMeltBeam的示例武器。它会扫射出两条弯曲的能量光束并造成范围爆炸。</description>
<techLevel>Ultra</techLevel>
<graphicData>
<texPath>Wula/Weapon/WULA_RW_DM_Cannon</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>1.5</drawSize>
</graphicData>
<weaponTags>
<li>Wula_Ranged_Weapon_T4</li>
</weaponTags>
<uiIconScale>0.8</uiIconScale>
<soundInteract>Interact_ChargeRifle</soundInteract>
<recipeMaker>
<recipeUsers Inherit="False">
<li>WULA_Cube_Productor_Energy</li>
</recipeUsers>
<researchPrerequisite>WULA_Synth_Weapon_4_DM_Base_Technology</researchPrerequisite>
<unfinishedThingDef>UnfinishedWeapon</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">
<Steel>500</Steel>
<Plasteel>300</Plasteel>
<WULA_Dark_Matter_Item>6</WULA_Dark_Matter_Item>
</costList>
<statBases>
<WorkToMake>50000</WorkToMake>
<Mass>10</Mass>
<AccuracyTouch>0.6</AccuracyTouch>
<AccuracyShort>0.6</AccuracyShort>
<AccuracyMedium>0.6</AccuracyMedium>
<AccuracyLong>0.6</AccuracyLong>
<RangedWeapon_Cooldown>3</RangedWeapon_Cooldown>
</statBases>
<verbs>
<li Class="WulaFallenEmpire.VerbPropertiesExplosiveBeam">
<!-- 这里是我们新创建的 Verb Class -->
<verbClass>WulaFallenEmpire.Verb_ShootMeltBeam</verbClass>
<!-- 基础射线参数 -->
<hasStandardCommand>true</hasStandardCommand>
<warmupTime>1.5</warmupTime>
<range>25</range>
<burstShotCount>20</burstShotCount>
<ticksBetweenBurstShots>5</ticksBetweenBurstShots>
<beamDamageDef>Wula_Dark_Matter_Beam</beamDamageDef>
<!-- 核心光束塑形参数 -->
<beamFullWidthRange>12</beamFullWidthRange> <!-- 光束达到最大宽度的距离 -->
<beamWidth>5</beamWidth> <!-- 光束的最大宽度 -->
<beamMaxDeviation>0.8</beamMaxDeviation> <!-- 光束路径的随机偏移量 -->
<beamCurvature>0.7</beamCurvature> <!-- 光束的弯曲程度 -->
<beamStartOffset>0.5</beamStartOffset> <!-- 光束起始点距离发射者的偏移 -->
<!-- 视觉和音效 -->
<muzzleFlashScale>0</muzzleFlashScale>
<soundCastBeam>BeamGraser_Shooting</soundCastBeam>
<beamGroundFleckDef>Fleck_BeamBurn</beamGroundFleckDef>
<beamFleckChancePerTick>0.32</beamFleckChancePerTick>
<beamMoteDef>Mote_Wula_Dark_Matter_Beam</beamMoteDef>
<beamEndEffecterDef>GraserBeam_End</beamEndEffecterDef>
<beamLineFleckDef>Fleck_ShotGlow</beamLineFleckDef> <!-- 沿光束路径产生的粒子效果 -->
<beamLineFleckChanceCurve>
<points>
<li>(0, 0)</li>
<li>(0.65, 0.4)</li>
<li>(1, 0.75)</li>
</points>
</beamLineFleckChanceCurve>
<!-- 火焰效果 -->
<beamSetsGroundOnFire>true</beamSetsGroundOnFire> <!-- 光束是否点燃地面 -->
<beamChanceToStartFire>0.5</beamChanceToStartFire>
<beamChanceToAttachFire>0.5</beamChanceToAttachFire>
<beamFireSizeRange>0.2~0.4</beamFireSizeRange> <!-- 火焰大小范围 -->
<!-- 其他射线属性 -->
<beamHitsNeighborCells>true</beamHitsNeighborCells>
<stopBurstWithoutLos>false</stopBurstWithoutLos> <!-- 即使失去视野也继续扫射 -->
<!-- 攻击目标设置 -->
<targetParams>
<canTargetLocations>true</canTargetLocations>
</targetParams>
<!-- 爆炸参数 -->
<enableExplosion>true</enableExplosion>
<explosionShotInterval>3</explosionShotInterval> <!-- 每3次射击判定一次爆炸 -->
<explosionRadius>2.5</explosionRadius>
<explosionDamageDef>Wula_Dark_Matter_Flame</explosionDamageDef>
<explosionDamage>20</explosionDamage>
<explosionSound>Explosion_Bomb</explosionSound>
<chanceToStartFire>0.6</chanceToStartFire>
<screenShakeFactor>0.3</screenShakeFactor> <!-- 爆炸时的屏幕震动 -->
</li>
</verbs>
<tradeability>None</tradeability>
<thingSetMakerTags>
<li>RewardStandardQualitySuper</li>
</thingSetMakerTags>
</ThingDef>
</Defs>

View File

@@ -51,6 +51,24 @@
<comps>
<!--加上这个组件的机械体会直接跳过原版指挥范围判定-->
<li Class="WulaFallenEmpire.CompProperties_GlobalMechCommand" />
<li Class="WulaFallenEmpire.CompProperties_AutoMechCarrier">
<freeProduction>true</freeProduction> <!-- 改为消耗资源以测试独立成本 -->
<disableHediff>WULA_MechCarrierSwitchHediff</disableHediff>
<fixedIngredient>Steel</fixedIngredient>
<maxIngredientCount>500</maxIngredientCount> <!-- 定义最大资源容量 -->
<startingIngredientCount>500</startingIngredientCount> <!-- 定义初始资源数量 -->
<costPerPawn>999</costPerPawn> <!-- 设置一个很高的全局默认成本,以确保独立成本生效 -->
<cooldownTicks>9999</cooldownTicks> <!-- 设置一个很高的全局默认冷却,以确保独立冷却生效 -->
<productionQueue>
<li>
<pawnKind>Mech_WULA_Cat_Bomb</pawnKind>
<count>8</count>
<cooldownTicks>50</cooldownTicks> <!-- 独立冷却: 10秒 -->
</li>
</productionQueue>
<spawnEffecter>WarqueenWarUrchinsSpawned</spawnEffecter>
<spawnedMechEffecter>WarUrchinSpawned</spawnedMechEffecter>
</li>
</comps>
</ThingDef>
<AbilityDef>
@@ -96,6 +114,46 @@
<label>PMu-7A"斯托洛维耶"</label>
<description>乌拉帝国的机械开拓单元,通常被投放到荒无人烟的星球上进行初步开发。这种型号的开拓单元可以生产装备轻型武器的乌拉猫猫,并且可以在战场上投放低角护盾。</description>
<uiIconPath>Wula/Things/Wula_AI_Bomb_Mother/Wula_AI_Bomb_Mother_Icon</uiIconPath>
<comps Inherit="False">
<!--加上这个组件的机械体会直接跳过原版指挥范围判定-->
<li Class="WulaFallenEmpire.CompProperties_GlobalMechCommand" />
<li Class="WulaFallenEmpire.CompProperties_AutoMechCarrier">
<freeProduction>true</freeProduction> <!-- 改为消耗资源以测试独立成本 -->
<disableHediff>WULA_MechCarrierSwitchHediff</disableHediff>
<fixedIngredient>Steel</fixedIngredient>
<maxIngredientCount>500</maxIngredientCount> <!-- 定义最大资源容量 -->
<startingIngredientCount>500</startingIngredientCount> <!-- 定义初始资源数量 -->
<costPerPawn>999</costPerPawn> <!-- 设置一个很高的全局默认成本,以确保独立成本生效 -->
<cooldownTicks>9999</cooldownTicks> <!-- 设置一个很高的全局默认冷却,以确保独立冷却生效 -->
<productionQueue>
<li>
<pawnKind>Mech_WULA_Cat_Inf</pawnKind>
<count>8</count>
<cooldownTicks>50</cooldownTicks> <!-- 独立冷却: 10秒 -->
</li>
<li>
<pawnKind>Mech_WULA_Cat_Inf_Slow</pawnKind>
<count>8</count>
<cooldownTicks>600</cooldownTicks> <!-- 独立冷却: 10秒 -->
</li>
</productionQueue>
<spawnEffecter>WarqueenWarUrchinsSpawned</spawnEffecter>
<spawnedMechEffecter>WarUrchinSpawned</spawnedMechEffecter>
</li>
<li Class="CompProperties_CanBeDormant" />
<li Class="CompProperties_WakeUpDormant">
<wakeUpOnDamage>true</wakeUpOnDamage>
<wakeUpCheckRadius>30</wakeUpCheckRadius>
<wakeUpSound>MechanoidsWakeUp</wakeUpSound>
</li>
<li MayRequire="Ludeon.RimWorld.Biotech" Class="CompProperties_OverseerSubject">
<needsOverseerEffect>MechUncontrolled</needsOverseerEffect>
<delayUntilFeralCheck>60000</delayUntilFeralCheck>
<feralMtbDays>10</feralMtbDays>
<feralCascadeRadialDistance>25</feralCascadeRadialDistance>
</li>
<li MayRequire="Ludeon.RimWorld.Biotech" Class="CompProperties_MechRepairable" />
</comps>
</ThingDef>
<AbilityDef>
<defName>Wula_AI_Engineer_Mother_Attack_Ability</defName>
@@ -214,10 +272,19 @@
<shaderType>CutoutWithOverlay</shaderType>
<graphicClass>Graphic_Multi</graphicClass>
<drawSize>5</drawSize>
<shadowData>
<volume>(1.8, 1.6, 1.65)</volume>
<offset>(0, 0, -0.65)</offset>
</shadowData>
</bodyGraphicData>
</li>
</lifeStages>
<weaponMoney>99999~99999</weaponMoney>
<abilities>
<li>WULA_GiveSwitchHediff</li> <!-- 添加“停止生产”技能 -->
<li>WULA_RemoveSwitchHediff</li> <!-- 保留“恢复生产”技能 -->
<li>Wula_AI_Engineer_Mother_Ability</li>
</abilities>
<weaponTags>
<li>Wula_AI_Engineer_Mother_Weapon</li>
@@ -246,10 +313,11 @@
</li>
</lifeStages>
<weaponMoney>99999~99999</weaponMoney>
<weaponTags>
<li>Wula_AI_Engineer_Mother_Attack_Weapon</li>
</weaponTags>
<abilities>
<li>WULA_GiveSwitchHediff</li> <!-- 添加“停止生产”技能 -->
<li>WULA_RemoveSwitchHediff</li> <!-- 保留“恢复生产”技能 -->
<li>Wula_AI_Engineer_Mother_Attack_Ability</li>
</abilities>
<controlGroupPortraitZoom>0.3</controlGroupPortraitZoom>
</PawnKindDef>
@@ -404,7 +472,7 @@
<uiIconPath>Wula/Things/WULA_Commander_Cat/WULA_Cat_Thin_south</uiIconPath>
<race>
<baseHealthScale>3</baseHealthScale>
<thinkTreeConstant>SentryDroneConstant</thinkTreeConstant>
<thinkTreeConstant>WULA_Mech_Flyer_Constant</thinkTreeConstant>
<baseBodySize>0.7</baseBodySize>
<hasCorpse>false</hasCorpse>
<body>Mech_Light</body>
@@ -464,7 +532,7 @@
<description>乌拉帝国的一种小型机械体装备了一把DLa-4"云母"突击步枪附下挂刺刀,以在战场上拖住敌军。</description>
<uiIconPath>Wula/Things/WULA_Attack_Cat/WULA_Cat_Thin_south</uiIconPath>
<race>
<thinkTreeConstant>SentryDroneConstant</thinkTreeConstant>
<thinkTreeConstant>WULA_Mech_Flyer_Constant</thinkTreeConstant>
<baseBodySize>0.7</baseBodySize>
<hasCorpse>false</hasCorpse>
<body>Mech_Light</body>
@@ -519,7 +587,7 @@
</li>
</lifeStages>
</PawnKindDef>
<PawnKindDef ParentName="Mech_WULA_Cat_Soldier_PawnKind" MayRequire="Ludeon.RimWorld.Odyssey">
<PawnKindDef Name="Mech_WULA_Cat_Inf" ParentName="Mech_WULA_Cat_Soldier_PawnKind" MayRequire="Ludeon.RimWorld.Odyssey">
<defName>Mech_WULA_Cat_Inf</defName>
<label>步兵乌拉猫猫</label>
<race>Mech_WULA_Cat_Inf</race>
@@ -528,6 +596,9 @@
<li>Wula_Assault_Cat_Weapon</li>
</weaponTags>
</PawnKindDef>
<PawnKindDef ParentName="Mech_WULA_Cat_Inf" MayRequire="Ludeon.RimWorld.Odyssey">
<defName>Mech_WULA_Cat_Inf_Slow</defName>
</PawnKindDef>
<PawnKindDef ParentName="Mech_WULA_Cat_Soldier_PawnKind" MayRequire="Ludeon.RimWorld.Odyssey">
<defName>Mech_WULA_Cat_Commander</defName>
<label>指挥官乌拉猫猫</label>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 23 KiB

103
MCP/direct_mcp_client.py Normal file
View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
直接调用MCP服务器的Python接口
绕过Qoder IDE直接使用RimWorld知识库
"""
import os
import sys
# 添加MCP路径
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)
# 导入MCP服务器
from mcpserver_stdio import get_context
class DirectMCPClient:
"""直接调用MCP服务器的客户端"""
def __init__(self):
print("🚀 直接MCP客户端已启动")
print("📚 RimWorld知识库已加载")
def query(self, question: str) -> str:
"""查询RimWorld知识库"""
try:
print(f"🔍 正在查询: {question}")
result = get_context(question)
return result
except Exception as e:
return f"查询出错: {e}"
def interactive_mode(self):
"""交互模式"""
print("\n" + "="*60)
print("🎯 RimWorld知识库 - 交互模式")
print("输入问题查询知识库,输入 'quit''exit' 退出")
print("="*60)
while True:
try:
question = input("\n❓ 请输入您的问题: ").strip()
if question.lower() in ['quit', 'exit', '退出', 'q']:
print("👋 再见!")
break
if not question:
print("⚠️ 请输入有效的问题")
continue
print("\n🔄 正在搜索...")
result = self.query(question)
print("\n📖 查询结果:")
print("-" * 50)
print(result)
print("-" * 50)
except KeyboardInterrupt:
print("\n\n👋 用户中断,退出程序")
break
except Exception as e:
print(f"\n❌ 出现错误: {e}")
def main():
"""主函数"""
import argparse
parser = argparse.ArgumentParser(description='直接调用RimWorld MCP知识库')
parser.add_argument('--query', '-q', type=str, help='直接查询问题')
parser.add_argument('--interactive', '-i', action='store_true', help='进入交互模式')
args = parser.parse_args()
client = DirectMCPClient()
if args.query:
# 直接查询模式
result = client.query(args.query)
print("\n📖 查询结果:")
print("="*60)
print(result)
print("="*60)
elif args.interactive:
# 交互模式
client.interactive_mode()
else:
# 默认显示帮助
print("\n🔧 使用方法:")
print("1. 直接查询: python direct_mcp_client.py -q \"ThingDef是什么\"")
print("2. 交互模式: python direct_mcp_client.py -i")
print("3. 查看帮助: python direct_mcp_client.py -h")
# 演示查询
print("\n🎬 演示查询:")
demo_result = client.query("ThingDef")
print(demo_result[:500] + "..." if len(demo_result) > 500 else demo_result)
if __name__ == "__main__":
main()

View File

@@ -55,7 +55,8 @@ KNOWLEDGE_BASE_PATHS = [
# 初始化OpenAI客户端用于Qwen模型
qwen_client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
timeout=15.0 # 设置15秒超时避免MCP初始化超时
)
# 3. --- 向量缓存管理 ---
@@ -192,36 +193,47 @@ def find_most_similar_files(question_embedding, file_embeddings, top_n=3, min_si
return results
# 新增:重排序函数
def rerank_files(question, file_matches, top_n=5):
def rerank_files(question, file_matches, top_n=3): # 减少默认数量
"""使用DashScope重排序API对文件进行重新排序"""
try:
# 限制输入数量以减少超时风险
if len(file_matches) > 5: # 进一步限制最大输入数量以避免超时
file_matches = file_matches[:5]
# 准备重排序输入
documents = []
for match in file_matches:
# 读取文件内容
try:
with open(match['path'], 'r', encoding='utf-8') as f:
content = f.read()[:2000] # 限制内容长度以提高效率
content = f.read()[:1500] # 进一步限制内容长度以提高效率
documents.append(content)
except Exception as e:
logging.error(f"读取文件 {match['path']} 失败: {e}")
continue
if not documents:
logging.warning("重排序时未能读取任何文件内容")
return file_matches[:top_n]
# 调用重排序API
# 调用重排序API,添加超时处理
import time
start_time = time.time()
response = dashscope.TextReRank.call(
model='gte-rerank',
query=question,
documents=documents
)
elapsed_time = time.time() - start_time
logging.info(f"重排序API调用耗时: {elapsed_time:.2f}")
if response.status_code == 200:
# 根据重排序结果重新排序文件
reranked_results = []
for i, result in enumerate(response.output['results']):
if i < len(file_matches):
if i < len(file_matches) and i < len(documents): # 添加边界检查
reranked_results.append({
'path': file_matches[i]['path'],
'similarity': result['relevance_score']
@@ -417,6 +429,7 @@ def analyze_question_with_llm(question: str) -> dict:
messages=messages,
temperature=0.0, # 使用最低温度确保输出稳定
max_tokens=300,
timeout=12.0, # 12秒超时避免MCP初始化超时
stop=["\n\n"] # 防止模型生成过多内容
)
@@ -494,13 +507,20 @@ def get_context(question: str) -> str:
"""
logging.info(f"收到问题: {question}")
# 使用LLM分析问题
analysis = analyze_question_with_llm(question)
keywords = analysis["search_keywords"]
if not keywords:
logging.warning("无法从问题中提取关键词。")
return "无法从问题中提取关键词,请提供更具体的信息"
try:
# 使用LLM分析问题添加超时保护
analysis = analyze_question_with_llm(question)
keywords = analysis["search_keywords"]
if not keywords:
logging.warning("无法从问题中提取关键词。")
return "无法从问题中提取关键词,请提供更具体的信息。"
except Exception as e:
logging.error(f"LLM分析失败使用备用方案: {e}")
# 备用方案:使用简单的关键词提取
keywords = find_keywords_in_question(question)
if not keywords:
return "无法分析问题,请检查网络连接或稍后重试。"
logging.info(f"提取到关键词: {keywords}")
@@ -549,7 +569,7 @@ def get_context(question: str) -> str:
# 3. 向量化和相似度计算 (精准筛选)
# 增加超时保护:限制向量化的文件数量
MAX_FILES_TO_VECTORIZE = 50 # 增加处理文件数量
MAX_FILES_TO_VECTORIZE = 10 # 进一步减少处理文件数量以避免超时
if len(candidate_files) > MAX_FILES_TO_VECTORIZE:
logging.warning(f"候选文件过多 ({len(candidate_files)}),仅处理前 {MAX_FILES_TO_VECTORIZE} 个。")
candidate_files = candidate_files[:MAX_FILES_TO_VECTORIZE]
@@ -559,27 +579,36 @@ def get_context(question: str) -> str:
return "无法生成问题向量请检查API连接或问题内容。"
file_embeddings = []
for file_path in candidate_files:
for i, file_path in enumerate(candidate_files):
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# 添加处理进度日志
if i % 5 == 0: # 每5个文件记录一次进度
logging.info(f"正在处理第 {i+1}/{len(candidate_files)} 个文件: {os.path.basename(file_path)}")
file_embedding = get_embedding(content[:8000]) # 限制内容长度以提高效率
if file_embedding:
file_embeddings.append({'path': file_path, 'embedding': file_embedding})
except Exception as e:
logging.error(f"处理文件 {file_path} 时出错: {e}")
continue # 继续处理下一个文件,而不是完全失败
if not file_embeddings:
return "无法为任何候选文件生成向量。"
logging.warning("未能为任何候选文件生成向量。可能是由于API超时或其他错误。")
return "未能为任何候选文件生成向量,请稍后重试或减少搜索范围。"
# 找到最相似的多个文件
best_matches = find_most_similar_files(question_embedding, file_embeddings, top_n=10) # 增加返回数量以供重排序
best_matches = find_most_similar_files(question_embedding, file_embeddings, top_n=5) # 进一步减少返回数量以避免超时
if not best_matches:
return "计算向量相似度失败或没有找到足够相似的文件。"
# 新增:重排序处理
reranked_matches = rerank_files(question, best_matches, top_n=5)
# 新增:重排序处理(仅在找到足够多匹配项时执行)
if len(best_matches) > 2:
reranked_matches = rerank_files(question, best_matches, top_n=3) # 减少重排序数量
else:
reranked_matches = best_matches # 如果匹配项太少,跳过重排序以节省时间
# 提取代码内容
results_with_code = []
@@ -617,5 +646,19 @@ def get_context(question: str) -> str:
if __name__ == "__main__":
logging.info(f"Python Executable: {sys.executable}")
logging.info("RimWorld 向量知识库 (FastMCP版, v2.1-v4-model) 正在启动...")
# 快速启动:延迟初始化重量级组件
try:
# 验证基本配置
if not dashscope.api_key:
logging.warning("警告DASHSCOPE_API_KEY 未配置,部分功能可能受限。")
# 创建必要目录
os.makedirs(CACHE_DIR, exist_ok=True)
logging.info("MCP服务器快速启动完成等待客户端连接...")
except Exception as e:
logging.error(f"服务器启动时出错: {e}")
# 使用 'stdio' 传输协议
mcp.run(transport="stdio")

105
MCP/rimworld_query.py Normal file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RimWorld知识库命令行工具
快速查询工具无需Qoder IDE
"""
import os
import sys
import argparse
import json
# 添加MCP路径
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)
def quick_query(question: str, format_output: bool = True) -> str:
"""快速查询函数"""
try:
# 动态导入避免启动时的依赖检查
from mcpserver_stdio import get_context
result = get_context(question)
if format_output:
# 格式化输出
lines = result.split('\n')
formatted_lines = []
current_section = ""
for line in lines:
if line.startswith('--- 结果'):
current_section = f"\n🔍 {line}"
formatted_lines.append(current_section)
elif line.startswith('文件路径:'):
formatted_lines.append(f"📄 {line}")
elif line.strip() and not line.startswith('---'):
formatted_lines.append(line)
return '\n'.join(formatted_lines)
else:
return result
except Exception as e:
return f"❌ 查询失败: {e}"
def main():
parser = argparse.ArgumentParser(
description='RimWorld知识库命令行查询工具',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
使用示例:
%(prog)s "ThingDef是什么"
%(prog)s "如何创建新的Pawn" --raw
%(prog)s "建筑物定义" --output result.txt
%(prog)s --list-examples
"""
)
parser.add_argument('question', nargs='?', help='要查询的问题')
parser.add_argument('--raw', action='store_true', help='输出原始结果,不格式化')
parser.add_argument('--output', '-o', help='将结果保存到文件')
parser.add_argument('--list-examples', action='store_true', help='显示查询示例')
args = parser.parse_args()
if args.list_examples:
print("📚 RimWorld知识库查询示例:")
examples = [
"ThingDef的定义和用法",
"如何创建新的Building",
"Pawn类的主要方法",
"CompPower的使用方法",
"XML中的defName规则",
"GenConstruct.CanPlaceBlueprintAt",
"Building_Door的开关逻辑"
]
for i, example in enumerate(examples, 1):
print(f" {i}. {example}")
return
if not args.question:
parser.print_help()
return
print(f"🔍 正在查询: {args.question}")
result = quick_query(args.question, not args.raw)
if args.output:
try:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(result)
print(f"✅ 结果已保存到: {args.output}")
except Exception as e:
print(f"❌ 保存文件失败: {e}")
else:
print("\n" + "="*60)
print("📖 查询结果:")
print("="*60)
print(result)
print("="*60)
if __name__ == "__main__":
main()

123
MCP/test_config.py Normal file
View File

@@ -0,0 +1,123 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
验证MCP服务器配置和环境
"""
import os
import sys
import subprocess
import json
def test_mcp_configuration():
"""测试MCP配置是否正确"""
print("🔍 MCP配置验证工具")
print("=" * 50)
# 1. 检查Python环境
print(f"✓ Python解释器: {sys.executable}")
print(f"✓ Python版本: {sys.version}")
# 2. 检查工作目录
mcp_dir = os.path.dirname(os.path.abspath(__file__))
print(f"✓ MCP目录: {mcp_dir}")
# 3. 检查MCP SDK
sdk_path = os.path.join(mcp_dir, 'python-sdk', 'src')
print(f"✓ SDK路径: {sdk_path}")
print(f"✓ SDK存在: {os.path.exists(sdk_path)}")
# 4. 检查必要文件
server_script = os.path.join(mcp_dir, 'mcpserver_stdio.py')
env_file = os.path.join(mcp_dir, '.env')
print(f"✓ 服务器脚本: {os.path.exists(server_script)}")
print(f"✓ 环境文件: {os.path.exists(env_file)}")
# 5. 检查依赖包
try:
import mcp
print("✓ MCP SDK: 已安装")
except ImportError as e:
print(f"❌ MCP SDK: 未安装 - {e}")
try:
import dashscope
print("✓ DashScope: 已安装")
except ImportError as e:
print(f"❌ DashScope: 未安装 - {e}")
try:
import openai
print("✓ OpenAI: 已安装")
except ImportError as e:
print(f"❌ OpenAI: 未安装 - {e}")
# 6. 生成正确的配置
python_exe = sys.executable.replace("\\", "\\\\")
mcp_dir_escaped = mcp_dir.replace("\\", "\\\\")
sdk_path_escaped = sdk_path.replace("\\", "\\\\")
config = {
"mcpServers": {
"rimworld-knowledge-base": {
"command": python_exe,
"args": ["mcpserver_stdio.py"],
"cwd": mcp_dir_escaped,
"disabled": False,
"alwaysAllow": [],
"env": {
"PYTHONPATH": sdk_path_escaped
}
}
},
"tools": {
"rimworld-knowledge-base": {
"description": "从RimWorld本地知识库包括C#源码和XML中检索上下文。",
"server_name": "rimworld-knowledge-base",
"tool_name": "get_context",
"input_schema": {
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "关于RimWorld开发的问题应包含代码或XML中的关键词。"
}
},
"required": ["question"]
}
}
}
}
print("\\n📋 建议的MCP配置:")
print("=" * 50)
print(json.dumps(config, indent=2, ensure_ascii=False))
# 7. 测试服务器启动
print("\\n🚀 测试服务器启动:")
print("=" * 50)
try:
result = subprocess.run(
[sys.executable, server_script],
cwd=mcp_dir,
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
print("✓ 服务器可以正常启动")
else:
print(f"❌ 服务器启动失败: {result.stderr}")
except subprocess.TimeoutExpired:
print("✓ 服务器启动正常(超时保护触发)")
except Exception as e:
print(f"❌ 服务器测试失败: {e}")
print("\\n🎯 配置建议:")
print("=" * 50)
print("1. 复制上面的配置到 Qoder IDE 的 MCP 设置中")
print("2. 确保所有依赖包都已安装")
print("3. 检查 .env 文件中的 API Key 配置")
print("4. 重启 Qoder IDE 并重新连接 MCP 服务器")
if __name__ == "__main__":
test_mcp_configuration()

149
MCP/test_mcp.py Normal file
View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
最终功能测试验证MCP服务器是否能正常工作
"""
import os
import sys
import subprocess
import time
import json
def test_mcp_server_final():
"""最终测试MCP服务器功能"""
print("🔥 MCP服务器最终功能测试")
print("=" * 50)
# 获取当前目录
mcp_dir = os.path.dirname(os.path.abspath(__file__))
script_path = os.path.join(mcp_dir, 'mcpserver_stdio.py')
try:
# 1. 验证SDK安装
try:
import mcp
print("✅ MCP SDK: 已正确安装")
except ImportError:
print("❌ MCP SDK: 未安装")
return False
# 2. 启动服务器
print("🚀 启动MCP服务器...")
process = subprocess.Popen(
[sys.executable, script_path],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=mcp_dir
)
# 等待启动
time.sleep(2)
# 3. 初始化测试
init_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "final-test-client",
"version": "1.0.0"
}
}
}
print("📡 发送初始化请求...")
process.stdin.write(json.dumps(init_request) + '\n')
process.stdin.flush()
# 读取初始化响应
response = process.stdout.readline()
if response:
response_data = json.loads(response.strip())
if "result" in response_data:
print("✅ 初始化成功")
print(f" 服务器名称: {response_data['result'].get('serverInfo', {}).get('name', 'unknown')}")
print(f" 服务器版本: {response_data['result'].get('serverInfo', {}).get('version', 'unknown')}")
else:
print("❌ 初始化失败")
return False
else:
print("❌ 初始化无响应")
return False
# 4. 工具列表测试
tools_request = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
print("🔧 请求工具列表...")
process.stdin.write(json.dumps(tools_request) + '\n')
process.stdin.flush()
tools_response = process.stdout.readline()
if tools_response:
tools_data = json.loads(tools_response.strip())
if "result" in tools_data and "tools" in tools_data["result"]:
tools = tools_data["result"]["tools"]
print(f"✅ 发现 {len(tools)} 个工具:")
for tool in tools:
print(f" - {tool.get('name', 'unknown')}: {tool.get('description', 'no description')}")
else:
print("❌ 获取工具列表失败")
else:
print("❌ 工具列表请求无响应")
print("\n🎯 测试结果:")
print("✅ MCP服务器能够正常启动")
print("✅ 初始化协议工作正常")
print("✅ 工具发现机制正常")
print("\n✨ 所有基本功能测试通过!")
return True
except Exception as e:
print(f"❌ 测试过程中出错: {e}")
return False
finally:
# 清理进程
try:
process.terminate()
process.wait(timeout=5)
except:
try:
process.kill()
except:
pass
if __name__ == "__main__":
print("开始最终测试...")
success = test_mcp_server_final()
if success:
print("\n🎉 恭喜MCP服务器已完全修复并正常工作")
print("\n📋 现在您需要在Qoder IDE中更新配置")
print("1. 打开Qoder IDE设置 → MCP")
print("2. 更新配置文件,确保使用正确的绝对路径")
print("3. 重启Qoder IDE")
print("4. 在Agent模式下测试知识库查询")
print("\n建议的配置:")
print(json.dumps({
"mcpServers": {
"rimworld-knowledge-base": {
"command": sys.executable,
"args": ["mcpserver_stdio.py"],
"cwd": os.path.dirname(os.path.abspath(__file__)),
"disabled": False,
"alwaysAllow": []
}
}
}, indent=2))
else:
print("\n❌ 仍存在问题,需要进一步调试")

150
MCP/test_mcp_timeout_fix.py Normal file
View File

@@ -0,0 +1,150 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
测试MCP服务器超时修复
"""
import os
import sys
import subprocess
import time
import json
def test_mcp_server_timeout_fix():
"""测试MCP服务器是否能快速启动并响应"""
print("开始测试MCP服务器超时修复...")
# 获取当前目录
mcp_dir = os.path.dirname(os.path.abspath(__file__))
script_path = os.path.join(mcp_dir, 'mcpserver_stdio.py')
try:
# 启动MCP服务器进程
print("启动MCP服务器...")
start_time = time.time()
process = subprocess.Popen(
[sys.executable, script_path],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=mcp_dir
)
# 等待服务器启动(减少等待时间)
time.sleep(2) # 从3秒减少到2秒
startup_time = time.time() - start_time
print(f"服务器启动耗时: {startup_time:.2f}")
# 发送初始化请求
init_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "test-client",
"version": "1.0.0"
}
}
}
print("发送初始化请求...")
request_start = time.time()
process.stdin.write(json.dumps(init_request) + '\n')
process.stdin.flush()
# 读取响应
response_line = process.stdout.readline()
init_time = time.time() - request_start
if response_line:
print(f"✅ 初始化成功,耗时: {init_time:.2f}")
print(f"收到响应: {response_line.strip()}")
else:
print("❌ 初始化失败:无响应")
return False
# 发送简单的工具调用请求
tool_request = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_context",
"arguments": {
"question": "ThingDef" # 简单的测试查询
}
}
}
print("发送工具调用请求...")
tool_start = time.time()
process.stdin.write(json.dumps(tool_request) + '\n')
process.stdin.flush()
# 等待响应(减少超时时间)
timeout = 20 # 从30秒减少到20秒
response_received = False
while time.time() - tool_start < timeout:
if process.poll() is not None:
print("服务器进程已退出")
break
response_line = process.stdout.readline()
if response_line:
tool_time = time.time() - tool_start
print(f"✅ 工具调用成功,耗时: {tool_time:.2f}")
print(f"工具调用响应: {response_line.strip()[:200]}...") # 只显示前200个字符
response_received = True
break
time.sleep(0.1)
total_time = time.time() - start_time
if response_received:
print(f"✅ 测试成功MCP服务器能够正常处理请求")
print(f"总耗时: {total_time:.2f}")
# 性能评估
if total_time < 15:
print("🚀 性能优秀:服务器响应速度很快")
elif total_time < 25:
print("✅ 性能良好:服务器响应速度可接受")
else:
print("⚠️ 性能一般:服务器响应较慢,可能仍有超时风险")
else:
print("❌ 测试失败:超时未收到响应")
return False
except Exception as e:
print(f"❌ 测试出错: {e}")
return False
finally:
# 清理进程
try:
process.terminate()
process.wait(timeout=5)
except:
try:
process.kill()
except:
pass
print("测试完成")
return True
if __name__ == "__main__":
success = test_mcp_server_timeout_fix()
if success:
print("\n🎉 MCP服务器超时问题已修复")
print("现在可以在Qoder IDE中重新连接MCP服务器了。")
else:
print("\n❌ MCP服务器仍存在问题需要进一步调试。")

249
MCP/web_api_server.py Normal file
View File

@@ -0,0 +1,249 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RimWorld知识库Web API服务器
提供HTTP接口可以通过浏览器或HTTP客户端访问
"""
import os
import sys
import json
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
import threading
import webbrowser
# 添加MCP路径
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)
class RimWorldAPIHandler(BaseHTTPRequestHandler):
"""HTTP请求处理器"""
def do_GET(self):
"""处理GET请求"""
parsed_url = urlparse(self.path)
if parsed_url.path == '/':
self.serve_web_interface()
elif parsed_url.path == '/query':
self.handle_query_get(parsed_url)
elif parsed_url.path == '/api/query':
self.handle_api_query_get(parsed_url)
else:
self.send_error(404, "Not Found")
def do_POST(self):
"""处理POST请求"""
if self.path == '/api/query':
self.handle_api_query_post()
else:
self.send_error(404, "Not Found")
def serve_web_interface(self):
"""提供Web界面"""
html = """
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RimWorld 知识库</title>
<style>
body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }
.header { text-align: center; margin-bottom: 30px; }
.query-box { margin-bottom: 20px; }
input[type="text"] { width: 70%; padding: 10px; font-size: 16px; }
button { padding: 10px 20px; font-size: 16px; background: #007cba; color: white; border: none; cursor: pointer; }
button:hover { background: #005a8b; }
.result { margin-top: 20px; padding: 15px; background: #f5f5f5; border-radius: 5px; white-space: pre-wrap; }
.loading { color: #666; font-style: italic; }
.examples { margin-top: 20px; }
.example { cursor: pointer; color: #007cba; margin: 5px 0; }
.example:hover { text-decoration: underline; }
</style>
</head>
<body>
<div class="header">
<h1>🎮 RimWorld 知识库</h1>
<p>直接查询RimWorld游戏的C#源码和XML定义</p>
</div>
<div class="query-box">
<input type="text" id="queryInput" placeholder="输入您的问题例如ThingDef是什么" onkeypress="handleKeyPress(event)">
<button onclick="performQuery()">🔍 查询</button>
</div>
<div class="examples">
<h3>💡 查询示例:</h3>
<div class="example" onclick="setQuery('ThingDef的定义和用法')">• ThingDef的定义和用法</div>
<div class="example" onclick="setQuery('如何创建Building')">• 如何创建Building</div>
<div class="example" onclick="setQuery('Pawn类的主要方法')">• Pawn类的主要方法</div>
<div class="example" onclick="setQuery('CompPower的使用')">• CompPower的使用</div>
</div>
<div id="result" class="result" style="display: none;"></div>
<script>
async function performQuery() {
const input = document.getElementById('queryInput');
const result = document.getElementById('result');
const query = input.value.trim();
if (!query) {
alert('请输入查询问题');
return;
}
result.style.display = 'block';
result.textContent = '🔄 正在查询,请稍候...';
result.className = 'result loading';
try {
const response = await fetch('/api/query', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({question: query})
});
const data = await response.json();
if (data.success) {
result.textContent = data.result;
result.className = 'result';
} else {
result.textContent = '❌ 查询失败: ' + data.error;
result.className = 'result';
}
} catch (error) {
result.textContent = '❌ 网络错误: ' + error.message;
result.className = 'result';
}
}
function setQuery(query) {
document.getElementById('queryInput').value = query;
}
function handleKeyPress(event) {
if (event.key === 'Enter') {
performQuery();
}
}
</script>
</body>
</html>
"""
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.end_headers()
self.wfile.write(html.encode('utf-8'))
def handle_query_get(self, parsed_url):
"""处理GET查询请求"""
params = parse_qs(parsed_url.query)
question = params.get('q', [''])[0]
if not question:
self.send_error(400, "Missing 'q' parameter")
return
try:
from mcpserver_stdio import get_context
result = get_context(question)
self.send_response(200)
self.send_header('Content-Type', 'text/plain; charset=utf-8')
self.end_headers()
self.wfile.write(result.encode('utf-8'))
except Exception as e:
self.send_error(500, f"Query failed: {e}")
def handle_api_query_get(self, parsed_url):
"""处理API GET查询"""
params = parse_qs(parsed_url.query)
question = params.get('q', [''])[0]
if not question:
response = {"success": False, "error": "Missing 'q' parameter"}
else:
try:
from mcpserver_stdio import get_context
result = get_context(question)
response = {"success": True, "result": result}
except Exception as e:
response = {"success": False, "error": str(e)}
self.send_response(200)
self.send_header('Content-Type', 'application/json; charset=utf-8')
self.end_headers()
self.wfile.write(json.dumps(response, ensure_ascii=False).encode('utf-8'))
def handle_api_query_post(self):
"""处理API POST查询"""
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
try:
data = json.loads(post_data.decode('utf-8'))
question = data.get('question', '')
if not question:
response = {"success": False, "error": "Missing 'question' field"}
else:
from mcpserver_stdio import get_context
result = get_context(question)
response = {"success": True, "result": result}
except Exception as e:
response = {"success": False, "error": str(e)}
self.send_response(200)
self.send_header('Content-Type', 'application/json; charset=utf-8')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
self.wfile.write(json.dumps(response, ensure_ascii=False).encode('utf-8'))
def log_message(self, format, *args):
"""自定义日志输出"""
print(f"[{self.address_string()}] {format % args}")
def start_server(port=8080, open_browser=True):
"""启动Web服务器"""
server_address = ('', port)
httpd = HTTPServer(server_address, RimWorldAPIHandler)
print(f"🌐 RimWorld知识库Web服务器启动")
print(f"📍 服务地址: http://localhost:{port}")
print(f"🔍 查询API: http://localhost:{port}/api/query?q=您的问题")
print(f"💻 Web界面: http://localhost:{port}")
print("按 Ctrl+C 停止服务器")
if open_browser:
# 延迟打开浏览器
def open_browser_delayed():
import time
time.sleep(1)
webbrowser.open(f'http://localhost:{port}')
thread = threading.Thread(target=open_browser_delayed)
thread.daemon = True
thread.start()
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\n🛑 服务器已停止")
httpd.shutdown()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='RimWorld知识库Web API服务器')
parser.add_argument('--port', '-p', type=int, default=8080, help='服务器端口 (默认: 8080)')
parser.add_argument('--no-browser', action='store_true', help='不自动打开浏览器')
args = parser.parse_args()
start_server(args.port, not args.no_browser)

102
MCP/使用指南.md Normal file
View File

@@ -0,0 +1,102 @@
# RimWorld 知识库 - 绕过 Qoder IDE 使用指南
由于 Qoder IDE 中的 MCP 连接可能存在问题,我们提供了多种直接访问 RimWorld 知识库的方法。
## 🚀 方法 1直接 Python 调用
最简单直接的方法:
```bash
# 直接查询
python direct_mcp_client.py -q "ThingDef是什么"
# 交互模式
python direct_mcp_client.py -i
# 查看帮助
python direct_mcp_client.py -h
```
### 优点:
- ✅ 最快速,无需额外依赖
- ✅ 支持交互模式
- ✅ 直接在命令行使用
## 🛠️ 方法 2命令行工具
专业的命令行查询工具:
```bash
# 基本查询
python rimworld_query.py "ThingDef的定义"
# 保存结果到文件
python rimworld_query.py "Building类的方法" --output building_info.txt
# 显示原始结果(不格式化)
python rimworld_query.py "Pawn类" --raw
# 查看示例
python rimworld_query.py --list-examples
```
### 优点:
- ✅ 结果可保存到文件
- ✅ 支持原始输出格式
- ✅ 内置查询示例
## 📝 常用查询示例
```bash
# 查询类定义
"ThingDef的定义和用法"
"Building类有哪些方法"
"Pawn类的构造函数"
# 查询特定方法
"GenConstruct.CanPlaceBlueprintAt 方法"
"Building_Door 的开关逻辑"
"CompPower 的电力管理"
# 查询XML相关
"XML中的defName规则"
"如何定义新的ThingDef"
"建筑物的XML结构"
```
## 🔧 故障排除
### 如果出现导入错误:
```bash
# 确保在正确的目录
cd "C:\Steam\steamapps\common\RimWorld\Mods\3516260226\MCP"
# 检查 Python 环境
python -c "import mcp; print('MCP SDK 正常')"
```
### 如果查询结果为空:
- 尝试使用更具体的关键词
- 检查关键词拼写
- 使用英文类名或方法名
### 如果 Web 服务器无法启动:
- 检查端口是否被占用
- 尝试使用不同的端口号
- 确保没有其他程序占用该端口
## 💡 推荐使用场景
- **快速查询**: 使用方法 1 (direct_mcp_client.py)
- **批量处理**: 使用方法 2 (rimworld_query.py)
- **团队共享**: 使用方法 3 (web_api_server.py)
- **集成开发**: 使用 Web API 接口
## 🎯 性能优化
所有方法都已经过优化:
- 向量化处理限制在 10 个文件以内
- API 调用超时设置为 12-15 秒
- 支持本地缓存加速重复查询
现在您可以完全绕过 Qoder IDE直接使用 RimWorld 知识库了!

View File

@@ -5,7 +5,7 @@
"path": "../.."
},
{
"path": "../../../../Data"
"path": "../../../../../../workshop/content/294100/3551234893/1.6/Assemblies/ShelterShuttle"
}
],
"settings": {}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB