更新spawner机制
This commit is contained in:
Binary file not shown.
@@ -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
BIN
About/ModIcon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
@@ -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}"
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user