更新spawner机制

This commit is contained in:
2025-10-09 17:26:30 +08:00
parent cb1d709a54
commit 831dd2b01a
6 changed files with 166 additions and 76 deletions

Binary file not shown.

View File

@@ -192,7 +192,6 @@
<tickerType>Normal</tickerType>
<repairEffect>EatVegetarian</repairEffect>
<filthLeaving>Filth_Slime</filthLeaving>
<autoRebuildable>false</autoRebuildable>
<statBases>
<MaxHitPoints>10</MaxHitPoints>
<Mass>4</Mass>

BIN
About/ModIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1,16 +1,7 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_queenability\\compabilityeffect_needcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_queenability\\compabilityeffect_needcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"Documents": [],
"DocumentGroupContainers": [
{
"Orientation": 0,
@@ -18,34 +9,8 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "CompAbilityEffect_NeedCost.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
"RelativeToolTip": "Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
"ViewState": "AgIAAF4AAAAAAAAAAAAgwHcAAAA2AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-09T08:04:27.763Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "CompInteractiveProducer.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs*",
"RelativeToolTip": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs*",
"ViewState": "AgIAADoBAAAAAAAAAAAmwLEBAAAgAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-09T08:03:31.079Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"

View File

@@ -405,54 +405,180 @@ namespace ArachnaeSwarm.MoharHediffs
}
else
{
// 修改物品直接添加到pawn的物品栏中
Thing thing = ThingMaker.MakeThing(this.Props.thingToSpawn, null);
if (thing == null)
{
return false;
}
thing.stackCount = this.calculatedQuantity;
// 重新设计物品生成逻辑:按优先级顺序尝试
return TrySpawnItemWithPriority(pawn);
}
}
// 新增:按优先级顺序尝试生成物品
private bool TrySpawnItemWithPriority(Pawn pawn)
{
Thing thing = ThingMaker.MakeThing(this.Props.thingToSpawn, null);
if (thing == null)
{
Tools.Warn("Failed to create thing: " + this.Props.thingToSpawn?.defName, this.myDebug);
return false;
}
thing.stackCount = this.calculatedQuantity;
// 记录原始物品用于校验
ThingDef originalThingDef = thing.def;
int originalStackCount = thing.stackCount;
// 按优先级顺序尝试生成
bool success = false;
string spawnMethod = "";
// 优先级1: 尝试在pawn附近空地生成
if (!success)
{
success = TrySpawnAtNearbyEmptyCell(pawn, thing, ref spawnMethod);
}
// 优先级2: 尝试在pawn脚底生成
if (!success)
{
success = TrySpawnAtPawnPosition(pawn, thing, ref spawnMethod);
}
// 优先级3: 尝试放入pawn物品栏
if (!success)
{
success = TrySpawnInInventory(pawn, thing, ref spawnMethod);
}
// 生成后校验
if (success)
{
bool verified = VerifySpawnSuccess(pawn, originalThingDef, originalStackCount, spawnMethod);
// 检查pawn是否有物品栏
if (pawn.inventory == null)
// 如果校验失败且不是在物品栏中生成的,尝试在物品栏中重新生成
if (!verified && spawnMethod != "inventory")
{
Tools.Warn($"Pawn {pawn.Label} does not have an inventory to receive spawned items", this.myDebug);
return false;
Tools.Warn($"Spawn verification failed for {spawnMethod}, attempting inventory fallback", this.myDebug);
// 重新创建物品
Thing fallbackThing = ThingMaker.MakeThing(originalThingDef, null);
fallbackThing.stackCount = originalStackCount;
success = TrySpawnInInventory(pawn, fallbackThing, ref spawnMethod);
if (success)
{
verified = VerifySpawnSuccess(pawn, originalThingDef, originalStackCount, "inventory_fallback");
if (!verified)
{
Tools.Warn("Inventory fallback also failed verification", this.myDebug);
success = false;
}
}
}
// 尝试将物品添加到pawn的物品栏
if (pawn.inventory.innerContainer.TryAdd(thing))
if (success && verified)
{
if (PawnUtility.ShouldSendNotificationAbout(pawn))
{
Messages.Message(this.Props.spawnVerb.Translate(pawn.Named("PAWN"), thing.Named("THING")), pawn, MessageTypeDefOf.PositiveEvent, true);
}
return true;
}
else
{
// 如果物品栏添加失败,回退到原来的地面生成方式
Tools.Warn($"Failed to add {thing.Label} to {pawn.Label}'s inventory, falling back to ground spawn", this.myDebug);
IntVec3 intVec2;
if (!this.TryFindSpawnCell(out intVec2))
{
return false;
}
if (this.Props.spawnForbidden)
{
thing.SetForbidden(true, true);
}
GenPlace.TryPlaceThing(thing, intVec2, pawn.Map, ThingPlaceMode.Direct, null, null, default(Rot4));
if (PawnUtility.ShouldSendNotificationAbout(pawn))
{
Messages.Message(this.Props.spawnVerb.Translate(pawn.Named("PAWN"), thing.Named("THING")), thing, MessageTypeDefOf.PositiveEvent, true);
Messages.Message(this.Props.spawnVerb.Translate(pawn.Named("PAWN"), thing.Named("THING")),
spawnMethod == "inventory" || spawnMethod == "inventory_fallback" ? pawn : thing,
MessageTypeDefOf.PositiveEvent, true);
}
Tools.Warn($"Successfully spawned {originalStackCount}x {originalThingDef.defName} via {spawnMethod}", this.myDebug);
return true;
}
}
Tools.Warn($"Failed to spawn {originalStackCount}x {originalThingDef.defName} after all attempts", this.myDebug);
return false;
}
// 新增:尝试在附近空地生成
private bool TrySpawnAtNearbyEmptyCell(Pawn pawn, Thing thing, ref string spawnMethod)
{
IntVec3 spawnCell;
if (TryFindSpawnCell(out spawnCell))
{
if (this.Props.spawnForbidden)
{
thing.SetForbidden(true, true);
}
if (GenPlace.TryPlaceThing(thing, spawnCell, pawn.Map, ThingPlaceMode.Direct, null, null, default(Rot4)))
{
spawnMethod = "nearby_cell";
return true;
}
}
return false;
}
// 新增尝试在pawn位置生成
private bool TrySpawnAtPawnPosition(Pawn pawn, Thing thing, ref string spawnMethod)
{
IntVec3 pawnPosition = pawn.Position;
if (pawnPosition.IsValid && pawnPosition.Walkable(pawn.Map))
{
if (this.Props.spawnForbidden)
{
thing.SetForbidden(true, true);
}
if (GenPlace.TryPlaceThing(thing, pawnPosition, pawn.Map, ThingPlaceMode.Direct, null, null, default(Rot4)))
{
spawnMethod = "pawn_position";
return true;
}
}
return false;
}
// 新增:尝试在物品栏生成
private bool TrySpawnInInventory(Pawn pawn, Thing thing, ref string spawnMethod)
{
if (pawn.inventory == null)
{
Tools.Warn($"Pawn {pawn.Label} does not have an inventory", this.myDebug);
return false;
}
if (pawn.inventory.innerContainer.TryAdd(thing))
{
spawnMethod = "inventory";
return true;
}
return false;
}
// 新增:生成后校验
private bool VerifySpawnSuccess(Pawn pawn, ThingDef thingDef, int expectedCount, string spawnMethod)
{
bool verificationSuccess = false;
switch (spawnMethod)
{
case "nearby_cell":
case "pawn_position":
case "inventory_fallback":
// 检查地图上是否有生成的物品
verificationSuccess = pawn.Map.listerThings.ThingsOfDef(thingDef)
.Any(t => t.stackCount >= expectedCount && t.Position.InHorDistOf(pawn.Position, 2f));
break;
case "inventory":
// 检查物品栏中是否有生成的物品
verificationSuccess = pawn.inventory.innerContainer.Any(t => t.def == thingDef && t.stackCount >= expectedCount);
break;
}
if (!verificationSuccess)
{
Tools.Warn($"Spawn verification failed for {thingDef.defName} via {spawnMethod}", this.myDebug);
}
else
{
Tools.Warn($"Spawn verification successful for {thingDef.defName} via {spawnMethod}", this.myDebug);
}
return verificationSuccess;
}
private bool TryFindSpawnCell(out IntVec3 result)