更新spawner机制
This commit is contained in:
Binary file not shown.
@@ -192,7 +192,6 @@
|
|||||||
<tickerType>Normal</tickerType>
|
<tickerType>Normal</tickerType>
|
||||||
<repairEffect>EatVegetarian</repairEffect>
|
<repairEffect>EatVegetarian</repairEffect>
|
||||||
<filthLeaving>Filth_Slime</filthLeaving>
|
<filthLeaving>Filth_Slime</filthLeaving>
|
||||||
<autoRebuildable>false</autoRebuildable>
|
|
||||||
<statBases>
|
<statBases>
|
||||||
<MaxHitPoints>10</MaxHitPoints>
|
<MaxHitPoints>10</MaxHitPoints>
|
||||||
<Mass>4</Mass>
|
<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,
|
"Version": 1,
|
||||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||||
"Documents": [
|
"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}"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"DocumentGroupContainers": [
|
"DocumentGroupContainers": [
|
||||||
{
|
{
|
||||||
"Orientation": 0,
|
"Orientation": 0,
|
||||||
@@ -18,34 +9,8 @@
|
|||||||
"DocumentGroups": [
|
"DocumentGroups": [
|
||||||
{
|
{
|
||||||
"DockedWidth": 200,
|
"DockedWidth": 200,
|
||||||
"SelectedChildIndex": 1,
|
"SelectedChildIndex": -1,
|
||||||
"Children": [
|
"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",
|
"$type": "Bookmark",
|
||||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||||
|
|||||||
@@ -405,54 +405,180 @@ namespace ArachnaeSwarm.MoharHediffs
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 修改:物品直接添加到pawn的物品栏中
|
// 重新设计物品生成逻辑:按优先级顺序尝试
|
||||||
|
return TrySpawnItemWithPriority(pawn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增:按优先级顺序尝试生成物品
|
||||||
|
private bool TrySpawnItemWithPriority(Pawn pawn)
|
||||||
|
{
|
||||||
Thing thing = ThingMaker.MakeThing(this.Props.thingToSpawn, null);
|
Thing thing = ThingMaker.MakeThing(this.Props.thingToSpawn, null);
|
||||||
if (thing == null)
|
if (thing == null)
|
||||||
{
|
{
|
||||||
|
Tools.Warn("Failed to create thing: " + this.Props.thingToSpawn?.defName, this.myDebug);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
thing.stackCount = this.calculatedQuantity;
|
thing.stackCount = this.calculatedQuantity;
|
||||||
|
|
||||||
// 检查pawn是否有物品栏
|
// 记录原始物品用于校验
|
||||||
if (pawn.inventory == null)
|
ThingDef originalThingDef = thing.def;
|
||||||
|
int originalStackCount = thing.stackCount;
|
||||||
|
|
||||||
|
// 按优先级顺序尝试生成
|
||||||
|
bool success = false;
|
||||||
|
string spawnMethod = "";
|
||||||
|
|
||||||
|
// 优先级1: 尝试在pawn附近空地生成
|
||||||
|
if (!success)
|
||||||
{
|
{
|
||||||
Tools.Warn($"Pawn {pawn.Label} does not have an inventory to receive spawned items", this.myDebug);
|
success = TrySpawnAtNearbyEmptyCell(pawn, thing, ref spawnMethod);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试将物品添加到pawn的物品栏
|
// 优先级2: 尝试在pawn脚底生成
|
||||||
if (pawn.inventory.innerContainer.TryAdd(thing))
|
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);
|
||||||
|
|
||||||
|
// 如果校验失败且不是在物品栏中生成的,尝试在物品栏中重新生成
|
||||||
|
if (!verified && spawnMethod != "inventory")
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success && verified)
|
||||||
{
|
{
|
||||||
if (PawnUtility.ShouldSendNotificationAbout(pawn))
|
if (PawnUtility.ShouldSendNotificationAbout(pawn))
|
||||||
{
|
{
|
||||||
Messages.Message(this.Props.spawnVerb.Translate(pawn.Named("PAWN"), thing.Named("THING")), pawn, 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;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
// 如果物品栏添加失败,回退到原来的地面生成方式
|
|
||||||
Tools.Warn($"Failed to add {thing.Label} to {pawn.Label}'s inventory, falling back to ground spawn", this.myDebug);
|
|
||||||
|
|
||||||
IntVec3 intVec2;
|
Tools.Warn($"Failed to spawn {originalStackCount}x {originalThingDef.defName} after all attempts", this.myDebug);
|
||||||
if (!this.TryFindSpawnCell(out intVec2))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增:尝试在附近空地生成
|
||||||
|
private bool TrySpawnAtNearbyEmptyCell(Pawn pawn, Thing thing, ref string spawnMethod)
|
||||||
|
{
|
||||||
|
IntVec3 spawnCell;
|
||||||
|
if (TryFindSpawnCell(out spawnCell))
|
||||||
|
{
|
||||||
if (this.Props.spawnForbidden)
|
if (this.Props.spawnForbidden)
|
||||||
{
|
{
|
||||||
thing.SetForbidden(true, true);
|
thing.SetForbidden(true, true);
|
||||||
}
|
}
|
||||||
GenPlace.TryPlaceThing(thing, intVec2, pawn.Map, ThingPlaceMode.Direct, null, null, default(Rot4));
|
|
||||||
|
|
||||||
if (PawnUtility.ShouldSendNotificationAbout(pawn))
|
if (GenPlace.TryPlaceThing(thing, spawnCell, pawn.Map, ThingPlaceMode.Direct, null, null, default(Rot4)))
|
||||||
{
|
{
|
||||||
Messages.Message(this.Props.spawnVerb.Translate(pawn.Named("PAWN"), thing.Named("THING")), thing, MessageTypeDefOf.PositiveEvent, true);
|
spawnMethod = "nearby_cell";
|
||||||
}
|
|
||||||
return true;
|
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)
|
private bool TryFindSpawnCell(out IntVec3 result)
|
||||||
|
|||||||
Reference in New Issue
Block a user