文章目录
废话
本次尝试制作一个比较简单的mod,我们添加一些手办来代替原版丑陋的艺术雕刻品。然后添加一种新材料树脂(用树脂做手办听起来比较合理),让游戏看起来更萌一点。这个mod只需要添加xml数据就可以完成。
核心内容
1 创建数据定义
1.1 定义一个新的抽象物品 手办基类
原版的艺术雕刻图案随机,并且可以使用不同的材料,还带有一些奇怪的艺术描述,我们打算制作像钢琴一样可以拆卸的物品,但是作用只有增加美观度。于是我搜索这两个物品xml,这两个物品都继承了BuildingBase的xml数据,所以钢琴在原游戏中也是个建筑类别的存在,和一般的建筑属性做对比可以发现它的一些特殊的属性,比如可搬运(拆卸),我们也先建立一个抽象的xml让之后的手办都继承这些属性,我删除了钢琴的娱乐效果组件和雕刻的艺术组件,我们可以在C#写一个对应的新效果,但我没什么灵感。
<ThingDef Name="GarageKidBase" ParentName="BuildingBase" Abstract="True">
<!-- 是否允许穿过 -->
<passability>PassThroughOnly</passability>
<!-- 从上面路过的走的速度程度 -->
<pathCost>60</pathCost>
<!-- 袖珍物品 可拆卸搬运 -->
<minifiedDef>MinifiedThing</minifiedDef>
<!-- 图像在哪一层 -->
<altitudeLayer>Building</altitudeLayer>
<!-- 是否可以旋转 -->
<rotatable>false</rotatable>
<!-- <thingClass>Building_MusicalInstrument</thingClass> -->
<!-- ticker的执行频率 -->
<tickerType>Normal</tickerType>
<socialPropernessMatters>true</socialPropernessMatters>
<hasInteractionCell>true</hasInteractionCell>
<!-- 物品类别 -->
<thingCategories>
<li>BuildingsArt</li>
</thingCategories>
<!-- 交易标签 -->
<tradeTags>
<li>Art</li>
</tradeTags>
<statBases>
<!-- 质量 -->
<Mass>1</Mass>
</statBases>
<!-- 配方 -->
<recipeMaker>
<!-- 某种工作加成,有cook和drug,不太清楚填通用就好了 -->
<workSpeedStat>GeneralLaborSpeed</workSpeedStat>
<!-- 制作时有加成的技能 -->
<workSkill>Artistic</workSkill>
<!-- 工作特效 -->
<effectWorking>Sculpt</effectWorking>
<!-- 工作音效 -->
<soundWorking>Recipe_Sculpt</soundWorking>
<!-- 未完成的物品对应哪个def -->
<unfinishedThingDef>UnfinishedGarageKid</unfinishedThingDef>
</recipeMaker>
<!-- 地形支持需求 可选 Light Medium Heavy Bridgeable Diggable -->
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
<comps>
<li>
<!-- 这个组件有品质效果,美观度等属性会变化 -->
<compClass>CompQuality</compClass>
</li>
</comps>
</ThingDef>
这里的recipeMaker标签可以设定一些获取这个物品的要求,比如需要什么样的前置研究,在哪里制作,需要什么技能,与之配套的是costList标签,控制消耗多少材料,第一次遇到没见过的标签,记得善用搜索+翻译,这样大概就知道他的作用了。
1.2 源源不断的手办(Garage Kid)
通过我们之前完成的基类,我们只需要再添加一些必要的数据,就可以制造各种各样的手办了,反正它们最主要的区别只有纹理不一样。这里的tex我随便找的,还没有合适的素材,需要一个懂美术的朋友
<ThingDef ParentName="GarageKidBase">
<defName>GarageKid_Chicken</defName>
<label>手办(鸡)</label>
<description>一个关于鸡的手办,真是太美了</description>
<graphicData>
<texPath>Things/Building/SR_GarageKid/GarageKid_Chicken</texPath>
<graphicClass>Graphic_Single</graphicClass>
<!-- <drawSize>(2.6,2.6)</drawSize>
<shadowData>
<volume>(1.93,1,1.69)</volume>
<offset>(-0.03,0,-0.1)</offset>
</shadowData> -->
</graphicData>
<!-- 是否妨碍视线 -->
<blockWind>false</blockWind>
<fillPercent>1.0</fillPercent>
<rotatable>false</rotatable>
<statBases>
<!-- 耐久 -->
<MaxHitPoints>300</MaxHitPoints>
<!-- 制作工作量 -->
<WorkToMake>30000</WorkToMake>
<!-- 可燃性 -->
<Flammability>1.0</Flammability>
<!-- 出售加成 -->
<SellPriceFactor>1.5</SellPriceFactor>
<Beauty>400</Beauty>
</statBases>
<canOverlapZones>false</canOverlapZones>
<size>(1,1)</size>
<!-- 品质奖励的标准 -->
<thingSetMakerTags><li>RewardStandardQualitySuper</li></thingSetMakerTags>
<recipeMaker>
<!-- 需要的技能6级制造6级艺术 可以复合 -->
<skillRequirements>
<Crafting>6</Crafting>
<Artistic>6</Artistic>
</skillRequirements>
<!-- 需要的前置研究 -->
<!-- <researchPrerequisite>Piano</researchPrerequisite> -->
<!-- 在什么地方制造 -->
<recipeUsers>
<li>TableSculpting</li>
</recipeUsers>
</recipeMaker>
<costList>
<Resin>100</Resin>
</costList>
</ThingDef>
1.3 新材料(Stuff)
这里的Resin是我定义的新材料树脂,这里还没有创建这个材料,我们就顺便定义一下新资源,同样,我们参考了Core中Steel的数据,但与之不同的是我们不会用它制作防具和武器,所以它影响制作的物品锋利度防护度相关的部分被我删掉了,然后还需要把它设置为一种制造材料,同样是原版没有的。我们只要仿造添加一个就好。
新材料的代码
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="ResourceBase">
<defName>Resin</defName>
<label>树脂</label>
<description>树脂是一种粘性物质,由一些树木提取,用于制作手办</description>
<tickerType>Normal</tickerType>
<graphicData>
<texPath>Things/Item/Resource/Chemfuel</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>0.85</drawSize>
</graphicData>
<stackLimit>150</stackLimit>
<healthAffectsPrice>false</healthAffectsPrice>
<statBases>
<MaxHitPoints>50</MaxHitPoints>
<MarketValue>2.3</MarketValue>
<Mass>0.01</Mass>
<Flammability>1.2</Flammability>
<DeteriorationRate>1.0</DeteriorationRate>
</statBases>
<stuffProps>
<categories>
<li>Resin</li>
</categories>
<commonality>0.15</commonality>
<color>(245,245,245)</color>
<statFactors>
<Flammability>1.2</Flammability>
<MaxHitPoints>1.3</MaxHitPoints>
</statFactors>
</stuffProps>
<thingCategories>
<li>Manufactured</li>
</thingCategories>
</ThingDef>
</Defs>
设置为制造材料
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<StuffCategoryDef>
<defName>Resin</defName>
<label>树脂</label>
</StuffCategoryDef>
</Defs>
stuffProps标签里的categories控制了它属于哪种制造材料,如果不填写的话会报错,但并不会崩溃,游戏会把它设置为默认的木头材质。此外它还影响了未完成品的名称,我们后面会说到。
1.4 添加配方(Recipe)
其实我们已经在新的手办物品中设置了配方了,通过recipeMaker标签和costList标签。但还有另一种更常用的标签,在Core中,Recipe相关的都是制造配方,通过Recipe可以做到复杂的合成,比如可以设置所有种类的皮革中除了某几种以外都可以算为一种材料。
我们也尝试使用Recipe设置一个用木头在燃料加工台制作树脂的配方
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<RecipeDef>
<defName>Make_Resin</defName>
<label>制作树脂</label>
<description>从树木中提取树脂</description>
<jobString>正在制作树脂</jobString>
<workSpeedStat>GeneralLaborSpeed</workSpeedStat>
<effectWorking>Cremate</effectWorking>
<soundWorking>Recipe_Cremate</soundWorking>
<workAmount>1800</workAmount>
<allowMixingIngredients>true</allowMixingIngredients>
<targetCountAdjustment>50</targetCountAdjustment>
<recipeUsers>
<li>BiofuelRefinery</li>
</recipeUsers>
<ingredients>
<li>
<filter>
<thingDefs>
<li>WoodLog</li>
</thingDefs>
</filter>
<count>50</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>WoodLog</li>
</thingDefs>
</fixedIngredientFilter>
<products>
<Resin>10</Resin>
</products>
<workSkill>Crafting</workSkill>
</RecipeDef>
</Defs>
1.5 未完成物品
差点忘了这个东西,你一定注意到了
<!-- 未完成的物品对应哪个def -->
<unfinishedThingDef>UnfinishedGarageKid</unfinishedThingDef>
它对应这个物品未完成的样子和描述,不过它有个bug,它的名称和描述是没办法显示在游戏中的,总是以 未完成的+材质+制作品名字这种格式命名,描述也会被替换为制作品的描述,但这个def并不是不起作用的,游戏中会读取它的纹理。我还没有素材,用原版某个艺术品未完成的图片代替了。
<ThingDef ParentName="UnfinishedBase">
<defName>UnfinishedGarageKid</defName>
<label>未完成的手办</label>
<description>一个未完成的手办</description>
<!-- 什么类型的材料 享受对应的属性 -->
<stuffCategories>
<li>Resin</li>
</stuffCategories>
<graphicData>
<texPath>Things/Item/Unfinished/UnfinishedMusicalInstrument</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
</ThingDef>
1.6 测试
简单测试了树脂的制作,手办的制作,需求的条件,以及拆卸之类的操作,质量太轻是有bug的,游戏改成英文方便我们了解目标物品在core的名字是什么。
源码链接
1.7 本地化
追加一下xml本地化的内容。
上一篇里介绍了C#代码中的本地化,今天介绍一下如何本地化xml中的参数。以英文为例,在Languages下建立English文件夹,然后在English/下建立DefInjected目录,它的原理也是利用patch的方式覆盖原有的数据。
在DefInjected下建立一些对应的Def路径,创建对应原xml文件的名字,修改内部的参数,格式参照
原xml文件
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<RecipeDef>
<defName>Make_Resin</defName>
<label>制作树脂</label>
<description>从树木中提取树脂</description>
<jobString>正在制作树脂</jobString>
<workSpeedStat>GeneralLaborSpeed</workSpeedStat>
<effectWorking>Cremate</effectWorking>
<soundWorking>Recipe_Cremate</soundWorking>
<workAmount>1800</workAmount>
<allowMixingIngredients>true</allowMixingIngredients>
<targetCountAdjustment>50</targetCountAdjustment>
<recipeUsers>
<li>BiofuelRefinery</li>
</recipeUsers>
<ingredients>
<li>
<filter>
<thingDefs>
<li>WoodLog</li>
</thingDefs>
</filter>
<count>50</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>WoodLog</li>
</thingDefs>
</fixedIngredientFilter>
<products>
<Resin>10</Resin>
</products>
<workSkill>Crafting</workSkill>
</RecipeDef>
</Defs>
对应的补丁文件
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>
<Make_Resin.label>make resins</Make_Resin.label>
<Make_Resin.description>Make resins from woods</Make_Resin.description>
<Make_Resin.jobString>Making resins</Make_Resin.jobString>
</LanguageData>
这里有一点需要特别注意
你的翻译xml文件必须与mod中的xml数据文件同名,并且放在一个与原版Def路径有关联的路径中,才会生效!
这个关联的形式并不是与原路径名字一样,这一点坑了我半天。代码报错查不到,去论坛找了半天信息才了解到。
一般的核心路径如RecipeDefs与之对应的路径为RecipeDef,去掉复数“s”
而ThingDefs_Buildings,ThingDefs_Items之类的路径会被归并为ThingDef路径,只有这样命名,目录下的翻译文件才会生效!
这个不怎么起眼的信息在RimWorld\Data\Core\Languages\English\About.txt文件里有说明到
我描述的可能不太清楚,具体应该看下我源码中路径的名字,你很快就可以搞清楚。
最后我想说的是,这个翻译方式是以最原始的原理翻译游戏中调用到的文件,实际翻译的话是有大佬写好翻译工具的,可能会更简便一下。由于我没做过汉化工作,如何使用工具以及去哪下载都不清楚。对翻译感兴趣的人推荐询问汉化组成员。
如果这篇文章对你有帮助,点赞收藏支持一下呗!