diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 59b7d73..25d3265 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml b/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml index 6452df5..5e62cc4 100644 --- a/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml +++ b/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml @@ -25,6 +25,11 @@
  • ARA_Proj_EggSac
  • +
  • + Food + 4 + 食物不足 +
  • @@ -60,6 +65,11 @@ 3 +
  • + Food + 0.5 + 食物不足 +
  • diff --git a/1.6/1.6/Defs/BodyAndPartDefs/ARA_Bodyparts.xml b/1.6/1.6/Defs/BodyAndPartDefs/ARA_Bodyparts.xml index 6196576..1f1f860 100644 --- a/1.6/1.6/Defs/BodyAndPartDefs/ARA_Bodyparts.xml +++ b/1.6/1.6/Defs/BodyAndPartDefs/ARA_Bodyparts.xml @@ -14,7 +14,7 @@
  • ARA_Dorsum - 0.036 + 0
  • Torso
  • @@ -42,7 +42,7 @@
  • ARA_Sternum - 0.036 + 0
  • Torso
  • @@ -154,7 +154,7 @@
  • ARA_Tail - 0.025 + 0 Bottom Inside @@ -346,6 +346,7 @@ true
  • Hands
  • +
  • HeadClaw
  • @@ -401,6 +402,7 @@ true
  • Hands
  • +
  • HeadClaw
  • diff --git a/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml b/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml index efd5b1b..47be407 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml @@ -5,13 +5,13 @@ ARA_InteractiveEggSac 一个黏滑的囊状物,可以通过交互来孵化特定的昆虫。 - Building + ArachnaeSwarm.Building_Incubator Building (1,1) - Things/Building/EggSac - Graphic_Random - (1.5,1.5) + Things/Building/EggSac + Graphic_Random + (1.5,1.5) Building PassThroughOnly @@ -20,39 +20,44 @@ Normal Light - 200 - 0.4 - -6 + 200 + 0.4 + -6 - true - false - false - false - true - true - false + true + false + false + false + true + true + false + + Things/Building/Natural/Hive + Graphic_Random + 1.6 + -
  • - 6 - (113,141,117,0) -
  • -
  • - -
  • Megascarab
  • -
  • Spelopede
  • -
  • Megaspider
  • - - -
  • ARA_ArachnaeQueen
  • -
    - 300 - true - -
  • - CocoonDestroyed -
  • +
  • + 6 + (113,141,117,0) +
  • +
  • + +
  • Megascarab
  • +
  • Spelopede
  • +
  • Megaspider
  • + + +
  • ARA_ArachnaeQueen
  • +
    + 300 + true + +
  • + CocoonDestroyed +
  • diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index 1ee6c58..08e78d2 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -73,7 +73,9 @@ + + diff --git a/Source/ArachnaeSwarm/Building_Incubator.cs b/Source/ArachnaeSwarm/Building_Incubator.cs new file mode 100644 index 0000000..ba4158f --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Incubator.cs @@ -0,0 +1,34 @@ +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + public class Building_Incubator : Building + { + public CompSpawnPawnFromList SpawnComp => GetComp(); + + public GraphicData hatchingGraphicData; + private Graphic hatchingGraphic; + + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + if (hatchingGraphicData != null) + { + hatchingGraphic = hatchingGraphicData.Graphic; + } + } + + public override Graphic Graphic + { + get + { + if (SpawnComp != null && SpawnComp.IsHatching && hatchingGraphic != null) + { + return hatchingGraphic; + } + return base.Graphic; + } + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/CompAbilityEffect_NeedCost.cs b/Source/ArachnaeSwarm/CompAbilityEffect_NeedCost.cs new file mode 100644 index 0000000..41613ba --- /dev/null +++ b/Source/ArachnaeSwarm/CompAbilityEffect_NeedCost.cs @@ -0,0 +1,54 @@ +using RimWorld; +using RimWorld.Planet; +using Verse; + +namespace ArachnaeSwarm +{ + public class CompProperties_AbilityNeedCost : CompProperties_AbilityEffect + { + public NeedDef needDef; + public float needCost; + public string failMessage; + + public CompProperties_AbilityNeedCost() + { + compClass = typeof(CompAbilityEffect_NeedCost); + } + } + + public class CompAbilityEffect_NeedCost : CompAbilityEffect + { + public new CompProperties_AbilityNeedCost Props => (CompProperties_AbilityNeedCost)props; + + public override bool GizmoDisabled(out string reason) + { + Pawn caster = parent.pawn; + if (caster != null && caster.needs != null) + { + if (caster.needs.TryGetNeed(Props.needDef, out Need need)) + { + if (need.CurLevel < Props.needCost) + { + reason = Props.failMessage; + return true; + } + } + } + reason = null; + return false; + } + + public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) + { + base.Apply(target, dest); + Pawn caster = parent.pawn; + if (caster != null && caster.needs != null) + { + if (caster.needs.TryGetNeed(Props.needDef, out Need need)) + { + need.CurLevel -= Props.needCost; + } + } + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/CompSpawnPawnFromList.cs b/Source/ArachnaeSwarm/CompSpawnPawnFromList.cs index 07027e4..ce05723 100644 --- a/Source/ArachnaeSwarm/CompSpawnPawnFromList.cs +++ b/Source/ArachnaeSwarm/CompSpawnPawnFromList.cs @@ -13,6 +13,7 @@ namespace ArachnaeSwarm private int spawnUntilTick = -1; private PawnKindDef spawningPawnKind; private PawnKindDef selectedPawnKind; + public bool IsHatching => spawnUntilTick > 0; public override IEnumerable CompFloatMenuOptions(Pawn selPawn) { @@ -40,6 +41,7 @@ namespace ArachnaeSwarm } } + public void StartIncubation() { spawningPawnKind = selectedPawnKind; @@ -55,6 +57,8 @@ namespace ArachnaeSwarm } } + + private void SpawnPawn(PawnKindDef pawnKind) { try @@ -71,34 +75,38 @@ namespace ArachnaeSwarm return; } - Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawnKind, parent.Faction)); - if (pawn == null) + int count = Props.spawnCount.RandomInRange; + for (int i = 0; i < count; i++) { - Log.Error($"CompSpawnPawnFromList: Failed to generate pawn of kind {pawnKind.defName} for faction {parent.Faction?.Name ?? "null"}."); - return; - } - - if (GenSpawn.Spawn(pawn, parent.Position, parent.Map) == null) - { - Log.Error($"CompSpawnPawnFromList: Failed to spawn pawn {pawn} at {parent.Position}."); - if (!pawn.Destroyed) + Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawnKind, parent.Faction)); + if (pawn == null) { - pawn.Destroy(); + Log.Error($"CompSpawnPawnFromList: Failed to generate pawn of kind {pawnKind.defName} for faction {parent.Faction?.Name ?? "null"}."); + continue; } - return; - } - if (Props.lordJob != null) - { - try + if (GenSpawn.Spawn(pawn, parent.Position, parent.Map) == null) { - LordJob lordJobInstance = (LordJob)System.Activator.CreateInstance(Props.lordJob); - Lord lord = LordMaker.MakeNewLord(parent.Faction, lordJobInstance, parent.Map); - lord.AddPawn(pawn); + Log.Error($"CompSpawnPawnFromList: Failed to spawn pawn {pawn} at {parent.Position}."); + if (!pawn.Destroyed) + { + pawn.Destroy(); + } + continue; } - catch (System.Exception e) + + if (Props.lordJob != null) { - Log.Error($"CompSpawnPawnFromList: Error creating LordJob {Props.lordJob?.Name ?? "null"} or assigning pawn {pawn}. Exception: {e}"); + try + { + LordJob lordJobInstance = (LordJob)System.Activator.CreateInstance(Props.lordJob); + Lord lord = LordMaker.MakeNewLord(parent.Faction, lordJobInstance, parent.Map); + lord.AddPawn(pawn); + } + catch (System.Exception e) + { + Log.Error($"CompSpawnPawnFromList: Error creating LordJob {Props.lordJob?.Name ?? "null"} or assigning pawn {pawn}. Exception: {e}"); + } } } @@ -114,6 +122,7 @@ namespace ArachnaeSwarm } } + public override string CompInspectStringExtra() { if (spawnUntilTick > 0) @@ -136,6 +145,7 @@ namespace ArachnaeSwarm base.PostExposeData(); Scribe_Values.Look(ref spawnUntilTick, "spawnUntilTick", -1); Scribe_Defs.Look(ref spawningPawnKind, "spawningPawnKind"); + Scribe_Defs.Look(ref selectedPawnKind, "selectedPawnKind"); } } } \ No newline at end of file diff --git a/Source/Documents/Project_Summary.md b/Source/Documents/Project_Summary.md new file mode 100644 index 0000000..605fe2a --- /dev/null +++ b/Source/Documents/Project_Summary.md @@ -0,0 +1,38 @@ +# 项目:可交互的虫卵囊 + +## 1. 核心目标 + +创建一个可交互的虫卵囊,它允许一个特定的 Pawn(阿拉克涅女皇种)通过右键菜单与它交互,从一个可配置的列表中选择一个 Pawn,并在经过一段可配置的延迟后,生成这个 Pawn。 + +## 2. 已完成的功能 + +* **创建了新的 VS 项目**: [`ArachnaeSwarm.csproj`](Source/ArachnaeSwarm/ArachnaeSwarm.csproj) +* **实现了核心的生成逻辑**: + * `CompProperties_SpawnPawnFromList.cs`: 定义了 XML 中可配置的属性,包括: + * `pawnKinds`: 可生成的 Pawn 列表。 + * `whitelist`: 可以与虫卵囊交互的 Pawn 列表。 + * `delay`: 孵化延迟。 + * `spawnCount`: 生成数量。 + * `destroyOnSpawn`: 生成后是否摧毁自身。 + * `lordJob`: 生成的 Pawn 要执行的集体任务。 + * `CompSpawnPawnFromList.cs`: 实现了核心的生成逻辑,包括: + * 生成右键菜单。 + * 处理孵化倒计时。 + * 生成指定数量的 Pawn。 + * 在检查面板上显示孵化状态和提示信息。 +* **实现了交互的 Job**: + * `ARA_Jobs.xml`: 定义了 `ARA_IncubateJob`。 + * `JobDriver_Incubate.cs`: 实现了让 Pawn 走到虫卵囊旁边并启动孵化过程的逻辑。 +* **实现了动态的图形切换**: + * `Building_Incubator.cs`: 创建了一个新的建筑基类,它会根据虫卵囊是否正在孵化来动态地改变自身的图形。 +* **创建了测试用的 Defs**: + * `ARA_InteractiveEggSac.xml`: 定义了一个可交互的虫卵囊,用于在游戏中测试新功能。 + * `ArachnaeSwarm_Keys.xml`: 定义了相关的本地化 `key`。 + +## 3. 当前状态 + +目前,项目已经基本完成了所有的核心功能,并且能够成功编译。但是,在最后一次构建时,我们遇到了一个编译错误,导致我们无法进行最终的测试。 + +## 4. 下一步计划 + +解决当前的编译错误,并成功构建项目,以便在游戏中进行最终的测试。 \ No newline at end of file