1
This commit is contained in:
Binary file not shown.
@@ -1,18 +1,34 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_ejectorgans\\compabilityeffect_ejectorgans.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_ejectorgans\\compabilityeffect_ejectorgans.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\\thing\\\u793A\u8303.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:thing\\\u793A\u8303.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_genestealer\\compabilityeffect_extractgene.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_genestealer\\compabilityeffect_extractgene.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\\thing\\highaltitudeflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:thing\\highaltitudeflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_terrainrestriction\\compabilityeffect_terrainrestriction .cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_terrainrestriction\\compabilityeffect_terrainrestriction .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\\thing\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:thing\\thingclassflyover.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\\buildings\\building_arachnaegravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_arachnaegravengine.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\\building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_building_refuelingvat\\building_refuelingvat.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\\hediffs\\ara_hediffterrainspawn\\comphediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hediffterrainspawn\\comphediffterrainspawn.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\\compabilityeffect_randomhediff.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\compabilityeffect_randomhediff.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
@@ -31,41 +47,87 @@
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "CompAbilityEffect_EjectOrgans.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_EjectOrgans\\CompAbilityEffect_EjectOrgans.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_EjectOrgans\\CompAbilityEffect_EjectOrgans.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_EjectOrgans\\CompAbilityEffect_EjectOrgans.cs",
|
||||
"RelativeToolTip": "Abilities\\ARA_EjectOrgans\\CompAbilityEffect_EjectOrgans.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAC4AAAAoAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-25T11:49:25.843Z",
|
||||
"Title": "\u793A\u8303.md",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\\u793A\u8303.md",
|
||||
"RelativeDocumentMoniker": "Thing\\\u793A\u8303.md",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\\u793A\u8303.md",
|
||||
"RelativeToolTip": "Thing\\\u793A\u8303.md",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAkAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
|
||||
"WhenOpened": "2025-10-27T03:36:17.112Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "CompAbilityEffect_ExtractGene.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
|
||||
"RelativeToolTip": "Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
|
||||
"ViewState": "AgIAABEAAAAAAAAAAAAAwCgAAAApAAAAAAAAAA==",
|
||||
"Title": "HighAltitudeFlyOver.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\HighAltitudeFlyOver.cs",
|
||||
"RelativeDocumentMoniker": "Thing\\HighAltitudeFlyOver.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\HighAltitudeFlyOver.cs",
|
||||
"RelativeToolTip": "Thing\\HighAltitudeFlyOver.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAACMAAAARAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-25T11:49:07.979Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-10-27T03:32:08.102Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "CompAbilityEffect_TerrainRestriction .cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_TerrainRestriction\\CompAbilityEffect_TerrainRestriction .cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_TerrainRestriction\\CompAbilityEffect_TerrainRestriction .cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_TerrainRestriction\\CompAbilityEffect_TerrainRestriction .cs",
|
||||
"RelativeToolTip": "Abilities\\ARA_TerrainRestriction\\CompAbilityEffect_TerrainRestriction .cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvwQAAAABAAAAAAAAAA==",
|
||||
"Title": "ThingclassFlyOver.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\ThingclassFlyOver.cs",
|
||||
"RelativeDocumentMoniker": "Thing\\ThingclassFlyOver.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\ThingclassFlyOver.cs*",
|
||||
"RelativeToolTip": "Thing\\ThingclassFlyOver.cs*",
|
||||
"ViewState": "AgIAAAcAAAAAAAAAAAAgwCEAAAAEAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-25T11:48:39.275Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-10-27T03:03:30.662Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "Building_RefuelingVat.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
|
||||
"RelativeDocumentMoniker": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
|
||||
"ViewState": "AgIAAEQAAAAAAAAAAAAAAEABAAAQAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-24T06:16:14.743Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "Building_ArachnaeGravEngine.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_ArachnaeGravEngine.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_ArachnaeGravEngine.cs",
|
||||
"ViewState": "AgIAAHwAAAAAAAAAAAAgwJcAAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-24T02:30:45.288Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"Title": "CompHediffTerrainSpawn.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
|
||||
"RelativeDocumentMoniker": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
|
||||
"RelativeToolTip": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
|
||||
"ViewState": "AgIAAB0AAAAAAAAAAAAswE0AAABHAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-23T08:00:28.236Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 6,
|
||||
"Title": "CompAbilityEffect_RandomHediff.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_RandomHediff.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\CompAbilityEffect_RandomHediff.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_RandomHediff.cs",
|
||||
"RelativeToolTip": "Abilities\\CompAbilityEffect_RandomHediff.cs",
|
||||
"ViewState": "AgIAALoAAAAAAAAAAAAqwNcAAAAZAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-22T06:34:08.063Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
<Compile Include="Storyteller\IncidentWorker_CustomRaid.cs" />
|
||||
<Compile Include="Storyteller\RaidWaveDef.cs" />
|
||||
<Compile Include="Storyteller\RaidWavePoolDef.cs" />
|
||||
<Compile Include="Thing\ThingclassFlyOver.cs" />
|
||||
<Compile Include="Verbs\Verb_ShootWithOffset.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowTemperatureRange\CompAbilityEffect_AbilityShowTemperatureRange.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowTemperatureRange\CompProperties_AbilityShowTemperatureRange.cs" />
|
||||
|
||||
171
Source/ArachnaeSwarm/Thing/HighAltitudeFlyOver.cs
Normal file
171
Source/ArachnaeSwarm/Thing/HighAltitudeFlyOver.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System.Collections.Generic;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using Verse.Sound;
|
||||
|
||||
[StaticConstructorOnStartup]
|
||||
public class HighAltitudeFlyOver : FlyOver
|
||||
{
|
||||
// 超高空飞行物特有的字段
|
||||
private Material cachedHighAltitudeShadowMaterial;
|
||||
private bool useCustomShadowGraphic = true;
|
||||
private float shadowIntensity = 0.6f; // 阴影强度
|
||||
|
||||
// 创建子类自己的 shadowPropertyBlock
|
||||
private static MaterialPropertyBlock highAltitudeShadowPropertyBlock = new MaterialPropertyBlock();
|
||||
|
||||
// 静态构造器:预加载阴影材质
|
||||
static HighAltitudeFlyOver()
|
||||
{
|
||||
// 可以在这里预加载特殊阴影材质
|
||||
}
|
||||
|
||||
// 属性:重写阴影材质
|
||||
protected new Material ShadowMaterial
|
||||
{
|
||||
get
|
||||
{
|
||||
if (cachedHighAltitudeShadowMaterial == null)
|
||||
{
|
||||
// 使用特殊的高空阴影材质
|
||||
var skyfallerShadow = def.skyfaller?.shadow;
|
||||
bool hasCustomShadow = skyfallerShadow != null && !skyfallerShadow.NullOrEmpty();
|
||||
|
||||
if (hasCustomShadow && useCustomShadowGraphic)
|
||||
{
|
||||
cachedHighAltitudeShadowMaterial = MaterialPool.MatFrom(
|
||||
skyfallerShadow,
|
||||
ShaderDatabase.Transparent,
|
||||
Color.white);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 默认使用圆形阴影
|
||||
cachedHighAltitudeShadowMaterial = MaterialPool.MatFrom(
|
||||
"Things/Skyfaller/SkyfallerShadowCircle",
|
||||
ShaderDatabase.Transparent);
|
||||
}
|
||||
}
|
||||
return cachedHighAltitudeShadowMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref useCustomShadowGraphic, "useCustomShadowGraphic", true);
|
||||
Scribe_Values.Look(ref shadowIntensity, "shadowIntensity", 0.6f);
|
||||
}
|
||||
|
||||
// 重写绘制方法:只绘制阴影,不绘制主体
|
||||
protected override void DrawAt(Vector3 drawLoc, bool flip = false)
|
||||
{
|
||||
// 完全跳过主体绘制,只绘制阴影
|
||||
DrawHighAltitudeShadow();
|
||||
}
|
||||
|
||||
// 专门的高空阴影绘制方法
|
||||
protected virtual void DrawHighAltitudeShadow()
|
||||
{
|
||||
Material shadowMaterial = ShadowMaterial;
|
||||
if (shadowMaterial == null)
|
||||
return;
|
||||
|
||||
Vector3 shadowPos = DrawPos;
|
||||
shadowPos.y = AltitudeLayer.Shadows.AltitudeFor();
|
||||
|
||||
// 高空阴影的特殊参数
|
||||
float shadowAlpha = CalculateHighAltitudeShadowAlpha();
|
||||
float shadowScale = CalculateHighAltitudeShadowScale();
|
||||
|
||||
// 设置阴影属性 - 使用子类自己的 property block
|
||||
highAltitudeShadowPropertyBlock.SetColor(ShaderPropertyIDs.Color,
|
||||
new Color(1f, 1f, 1f, shadowAlpha * shadowIntensity));
|
||||
|
||||
Vector3 scale = new Vector3(shadowScale, 1f, shadowScale);
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(shadowPos, Quaternion.identity, scale);
|
||||
|
||||
// 绘制阴影
|
||||
Graphics.DrawMesh(MeshPool.plane10, matrix, shadowMaterial,
|
||||
0, null, 0, highAltitudeShadowPropertyBlock);
|
||||
}
|
||||
|
||||
// 计算高空阴影透明度
|
||||
protected virtual float CalculateHighAltitudeShadowAlpha()
|
||||
{
|
||||
// 高空阴影应该更淡
|
||||
float baseAlpha = Mathf.Lerp(0.1f, 0.4f, currentProgress);
|
||||
|
||||
// 根据高度调整透明度(越高越淡)
|
||||
float heightFactor = Mathf.Clamp(1f - (altitude / 100f), 0.1f, 1f);
|
||||
|
||||
return baseAlpha * heightFactor;
|
||||
}
|
||||
|
||||
// 计算高空阴影大小
|
||||
protected virtual float CalculateHighAltitudeShadowScale()
|
||||
{
|
||||
// 高空阴影应该更大(透视效果)
|
||||
float baseScale = Mathf.Lerp(0.8f, 1.2f, currentProgress);
|
||||
|
||||
// 根据高度调整大小(越高越大)
|
||||
float heightFactor = 1f + (altitude / 50f);
|
||||
|
||||
return baseScale * heightFactor;
|
||||
}
|
||||
|
||||
// 重写 Tick 方法,可以添加高空特有的效果
|
||||
protected override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
|
||||
// 高空特有的效果:更稀少的粒子效果
|
||||
var motesPerCell = def.skyfaller?.motesPerCell;
|
||||
bool hasMotes = motesPerCell != null && motesPerCell > 0;
|
||||
|
||||
if (Rand.MTBEventOccurs(2f, 1f, 1f) && hasMotes)
|
||||
{
|
||||
CreateHighAltitudeEffects();
|
||||
}
|
||||
}
|
||||
|
||||
// 高空特效(更稀疏)
|
||||
protected virtual void CreateHighAltitudeEffects()
|
||||
{
|
||||
Vector3 effectPos = DrawPos;
|
||||
effectPos.y = AltitudeLayer.Weather.AltitudeFor(); // 使用天气层高度
|
||||
|
||||
// 高空特有的粒子效果
|
||||
FleckMaker.ThrowAirPuffUp(effectPos, base.Map);
|
||||
|
||||
// 偶尔生成云迹效果
|
||||
if (Rand.Chance(0.1f))
|
||||
{
|
||||
FleckMaker.ThrowSmoke(effectPos, base.Map, 3f);
|
||||
}
|
||||
}
|
||||
|
||||
// 新的工具方法:创建超高空飞行物
|
||||
public static HighAltitudeFlyOver MakeHighAltitudeFlyOver(ThingDef flyOverDef, IntVec3 start, IntVec3 end, Map map,
|
||||
float speed = 1f, float height = 50f, ThingOwner contents = null) // 默认高度更高
|
||||
{
|
||||
HighAltitudeFlyOver flyOver = (HighAltitudeFlyOver)ThingMaker.MakeThing(flyOverDef);
|
||||
flyOver.startPosition = start;
|
||||
flyOver.endPosition = end;
|
||||
flyOver.flightSpeed = speed;
|
||||
flyOver.altitude = height;
|
||||
|
||||
// 超高空特有的设置
|
||||
flyOver.playFlyOverSound = false; // 高空可能听不到声音
|
||||
flyOver.createShadow = true;
|
||||
|
||||
if (contents != null)
|
||||
{
|
||||
flyOver.innerContainer.TryAddRangeOrTransfer(contents);
|
||||
}
|
||||
|
||||
GenSpawn.Spawn(flyOver, start, map);
|
||||
return flyOver;
|
||||
}
|
||||
}
|
||||
313
Source/ArachnaeSwarm/Thing/ThingclassFlyOver.cs
Normal file
313
Source/ArachnaeSwarm/Thing/ThingclassFlyOver.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
using System.Collections.Generic;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using Verse.Sound;
|
||||
|
||||
[StaticConstructorOnStartup]
|
||||
public class FlyOver : ThingWithComps, IThingHolder
|
||||
{
|
||||
// 核心字段
|
||||
public ThingOwner innerContainer; // 内部物品容器
|
||||
public IntVec3 startPosition; // 起始位置
|
||||
public IntVec3 endPosition; // 结束位置
|
||||
public float flightSpeed = 1f; // 飞行速度
|
||||
public float currentProgress = 0f; // 当前进度 (0-1)
|
||||
public float altitude = 10f; // 飞行高度
|
||||
public float flightAngle = 0f; // 飞行角度
|
||||
|
||||
// 状态标志
|
||||
private bool hasStarted = false;
|
||||
private bool hasCompleted = false;
|
||||
|
||||
// 音效系统
|
||||
private Sustainer flightSoundPlaying;
|
||||
|
||||
// 视觉效果
|
||||
private Material cachedShadowMaterial;
|
||||
private static MaterialPropertyBlock shadowPropertyBlock = new MaterialPropertyBlock();
|
||||
|
||||
// 配置字段
|
||||
public bool spawnContentsOnImpact = false; // 是否在结束时生成内容物
|
||||
public bool playFlyOverSound = true; // 是否播放飞越音效
|
||||
public bool createShadow = true; // 是否创建阴影
|
||||
|
||||
// 属性
|
||||
public override Vector3 DrawPos
|
||||
{
|
||||
get
|
||||
{
|
||||
// 线性插值计算当前位置
|
||||
Vector3 start = startPosition.ToVector3();
|
||||
Vector3 end = endPosition.ToVector3();
|
||||
|
||||
// 添加高度偏移
|
||||
Vector3 basePos = Vector3.Lerp(start, end, currentProgress);
|
||||
basePos.y = altitude;
|
||||
|
||||
return basePos;
|
||||
}
|
||||
}
|
||||
|
||||
public override Graphic Graphic
|
||||
{
|
||||
get
|
||||
{
|
||||
Thing thingForGraphic = GetThingForGraphic();
|
||||
if (thingForGraphic == this)
|
||||
{
|
||||
return base.Graphic;
|
||||
}
|
||||
return thingForGraphic.Graphic.ExtractInnerGraphicFor(thingForGraphic);
|
||||
}
|
||||
}
|
||||
|
||||
protected Material ShadowMaterial
|
||||
{
|
||||
get
|
||||
{
|
||||
if (cachedShadowMaterial == null && createShadow)
|
||||
{
|
||||
cachedShadowMaterial = MaterialPool.MatFrom("Things/Skyfaller/SkyfallerShadowCircle", ShaderDatabase.Transparent);
|
||||
}
|
||||
return cachedShadowMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
public FlyOver()
|
||||
{
|
||||
innerContainer = new ThingOwner<Thing>(this);
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Deep.Look(ref innerContainer, "innerContainer", this);
|
||||
Scribe_Values.Look(ref startPosition, "startPosition");
|
||||
Scribe_Values.Look(ref endPosition, "endPosition");
|
||||
Scribe_Values.Look(ref flightSpeed, "flightSpeed", 1f);
|
||||
Scribe_Values.Look(ref currentProgress, "currentProgress", 0f);
|
||||
Scribe_Values.Look(ref altitude, "altitude", 10f);
|
||||
Scribe_Values.Look(ref flightAngle, "flightAngle", 0f);
|
||||
Scribe_Values.Look(ref hasStarted, "hasStarted", false);
|
||||
Scribe_Values.Look(ref hasCompleted, "hasCompleted", false);
|
||||
Scribe_Values.Look(ref spawnContentsOnImpact, "spawnContentsOnImpact", false);
|
||||
}
|
||||
|
||||
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
||||
{
|
||||
base.SpawnSetup(map, respawningAfterLoad);
|
||||
|
||||
if (!respawningAfterLoad)
|
||||
{
|
||||
// 计算飞行角度(从起点指向终点的方向)
|
||||
Vector3 direction = (endPosition.ToVector3() - startPosition.ToVector3()).normalized;
|
||||
flightAngle = Mathf.Atan2(direction.z, direction.x) * Mathf.Rad2Deg;
|
||||
|
||||
// 设置初始位置
|
||||
base.Position = startPosition;
|
||||
hasStarted = true;
|
||||
|
||||
// 开始飞行音效
|
||||
if (playFlyOverSound && def.skyfaller?.floatingSound != null)
|
||||
{
|
||||
flightSoundPlaying = def.skyfaller.floatingSound.TrySpawnSustainer(
|
||||
SoundInfo.InMap(new TargetInfo(startPosition, map), MaintenanceType.PerTick));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
|
||||
if (!hasStarted || hasCompleted)
|
||||
return;
|
||||
|
||||
// 更新飞行进度
|
||||
currentProgress += flightSpeed * 0.001f; // 调整速度系数
|
||||
|
||||
// 更新当前位置(用于碰撞检测等)
|
||||
UpdatePosition();
|
||||
|
||||
// 维持飞行音效
|
||||
flightSoundPlaying?.Maintain();
|
||||
|
||||
// 检查是否到达终点
|
||||
if (currentProgress >= 1f)
|
||||
{
|
||||
CompleteFlyOver();
|
||||
}
|
||||
|
||||
// 可选:生成飞行轨迹特效
|
||||
if (Rand.MTBEventOccurs(0.5f, 1f, 1f) && def.skyfaller?.motesPerCell > 0)
|
||||
{
|
||||
CreateFlightEffects();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePosition()
|
||||
{
|
||||
// 更新物体的网格位置(用于碰撞检测等)
|
||||
Vector3 currentWorldPos = Vector3.Lerp(startPosition.ToVector3(), endPosition.ToVector3(), currentProgress);
|
||||
IntVec3 newPos = currentWorldPos.ToIntVec3();
|
||||
|
||||
if (newPos != base.Position && newPos.InBounds(base.Map))
|
||||
{
|
||||
base.Position = newPos;
|
||||
}
|
||||
}
|
||||
|
||||
private void CompleteFlyOver()
|
||||
{
|
||||
hasCompleted = true;
|
||||
currentProgress = 1f;
|
||||
|
||||
// 生成内容物(如果需要)
|
||||
if (spawnContentsOnImpact && innerContainer.Any)
|
||||
{
|
||||
SpawnContents();
|
||||
}
|
||||
|
||||
// 播放完成音效
|
||||
if (def.skyfaller?.impactSound != null)
|
||||
{
|
||||
def.skyfaller.impactSound.PlayOneShot(
|
||||
SoundInfo.InMap(new TargetInfo(endPosition, base.Map)));
|
||||
}
|
||||
|
||||
// 销毁自身
|
||||
Destroy();
|
||||
}
|
||||
|
||||
private void SpawnContents()
|
||||
{
|
||||
foreach (Thing thing in innerContainer)
|
||||
{
|
||||
if (thing != null && !thing.Destroyed)
|
||||
{
|
||||
GenPlace.TryPlaceThing(thing, endPosition, base.Map, ThingPlaceMode.Near);
|
||||
}
|
||||
}
|
||||
innerContainer.Clear();
|
||||
}
|
||||
|
||||
private void CreateFlightEffects()
|
||||
{
|
||||
// 在飞行轨迹上生成粒子效果
|
||||
Vector3 effectPos = DrawPos;
|
||||
effectPos.y = AltitudeLayer.MoteOverhead.AltitudeFor();
|
||||
FleckMaker.ThrowSmoke(effectPos, base.Map, 1f);
|
||||
|
||||
// 可选:根据速度生成更多效果
|
||||
if (flightSpeed > 2f)
|
||||
{
|
||||
FleckMaker.ThrowAirPuffUp(effectPos, base.Map);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DrawAt(Vector3 drawLoc, bool flip = false)
|
||||
{
|
||||
// 获取绘制位置和旋转
|
||||
Vector3 finalDrawPos = drawLoc;
|
||||
float extraRotation = flightAngle;
|
||||
|
||||
// 绘制主体
|
||||
Thing thingForGraphic = GetThingForGraphic();
|
||||
Graphic.Draw(finalDrawPos, thingForGraphic.Rotation, thingForGraphic, extraRotation);
|
||||
|
||||
// 绘制阴影
|
||||
DrawFlightShadow();
|
||||
}
|
||||
|
||||
protected virtual void DrawFlightShadow()
|
||||
{
|
||||
Material shadowMaterial = ShadowMaterial;
|
||||
if (shadowMaterial == null)
|
||||
return;
|
||||
|
||||
Vector3 shadowPos = DrawPos;
|
||||
shadowPos.y = AltitudeLayer.Shadows.AltitudeFor();
|
||||
|
||||
// 根据进度调整阴影大小和透明度
|
||||
float shadowAlpha = Mathf.Lerp(0.3f, 1f, currentProgress);
|
||||
float shadowScale = Mathf.Lerp(0.5f, 1.5f, currentProgress);
|
||||
|
||||
shadowPropertyBlock.SetColor(ShaderPropertyIDs.Color,
|
||||
new Color(1f, 1f, 1f, shadowAlpha));
|
||||
|
||||
Vector3 scale = new Vector3(shadowScale, 1f, shadowScale);
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(shadowPos, Quaternion.identity, scale);
|
||||
|
||||
Graphics.DrawMesh(MeshPool.plane10, matrix, shadowMaterial,
|
||||
0, null, 0, shadowPropertyBlock);
|
||||
}
|
||||
|
||||
// IThingHolder 接口实现
|
||||
public ThingOwner GetDirectlyHeldThings()
|
||||
{
|
||||
return innerContainer;
|
||||
}
|
||||
|
||||
public void GetChildHolders(List<IThingHolder> outChildren)
|
||||
{
|
||||
ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, GetDirectlyHeldThings());
|
||||
}
|
||||
|
||||
private Thing GetThingForGraphic()
|
||||
{
|
||||
if (def.graphicData != null || !innerContainer.Any)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
return innerContainer[0];
|
||||
}
|
||||
|
||||
// 工具方法:创建飞越物体
|
||||
public static FlyOver MakeFlyOver(ThingDef flyOverDef, IntVec3 start, IntVec3 end, Map map,
|
||||
float speed = 1f, float height = 10f, ThingOwner contents = null)
|
||||
{
|
||||
FlyOver flyOver = (FlyOver)ThingMaker.MakeThing(flyOverDef);
|
||||
flyOver.startPosition = start;
|
||||
flyOver.endPosition = end;
|
||||
flyOver.flightSpeed = speed;
|
||||
flyOver.altitude = height;
|
||||
|
||||
if (contents != null)
|
||||
{
|
||||
flyOver.innerContainer.TryAddRangeOrTransfer(contents);
|
||||
}
|
||||
|
||||
GenSpawn.Spawn(flyOver, start, map);
|
||||
return flyOver;
|
||||
}
|
||||
|
||||
//// 创建简单的飞越物体
|
||||
//public void CreateSimpleFlyOver()
|
||||
//{
|
||||
// // 获取地图边界
|
||||
// Map map = Find.CurrentMap;
|
||||
// IntVec3 start = new IntVec3(0, 0, map.Size.z / 2); // 左边中间
|
||||
// IntVec3 end = new IntVec3(map.Size.x, 0, map.Size.z / 2); // 右边中间
|
||||
|
||||
// // 创建飞越物体
|
||||
// FlyOver.MakeFlyOver(ThingDefOf.FlyOverShip, start, end, map,
|
||||
// speed: 1.5f, height: 15f);
|
||||
//}
|
||||
//// 创建带内容的飞越物体
|
||||
//public void CreateFlyOverWithContents()
|
||||
//{
|
||||
// Map map = Find.CurrentMap;
|
||||
// IntVec3 start = new IntVec3(map.Size.x / 2, 0, 0); // 上边中间
|
||||
// IntVec3 end = new IntVec3(map.Size.x / 2, 0, map.Size.z); // 下边中间
|
||||
|
||||
// // 创建内容容器
|
||||
// ThingOwner contents = new ThingOwner<Thing>();
|
||||
// contents.TryAdd(ThingMaker.MakeThing(ThingDefOf.Steel, 20));
|
||||
|
||||
// FlyOver flyOver = FlyOver.MakeFlyOver(ThingDefOf.CargoFlyOver, start, end, map,
|
||||
// speed: 1f, height: 12f, contents: contents);
|
||||
|
||||
// flyOver.spawnContentsOnImpact = true;
|
||||
//}
|
||||
}
|
||||
76
Source/ArachnaeSwarm/Thing/示范.md
Normal file
76
Source/ArachnaeSwarm/Thing/示范.md
Normal file
@@ -0,0 +1,76 @@
|
||||
// 在其他文件中调用:
|
||||
// 1. 简单飞越
|
||||
public void CreateSimpleFlyOverExample()
|
||||
{
|
||||
FlyOver flyOver = FlyOverUtility.CreateFlyOver(
|
||||
flyOverDef: ThingDefOf.FlyOverShip,
|
||||
map: Find.CurrentMap,
|
||||
startEdge: Rot4.West, // 从西边开始
|
||||
endEdge: Rot4.East, // 到东边结束
|
||||
speed: 1.5f,
|
||||
altitude: 12f
|
||||
);
|
||||
}
|
||||
// 2. 货运飞越
|
||||
public void CreateCargoFlyOverExample()
|
||||
{
|
||||
var cargoItems = new List<(ThingDef, int)>
|
||||
{
|
||||
(ThingDefOf.Steel, 50),
|
||||
(ThingDefOf.Plasteel, 20),
|
||||
(ThingDefOf.Component, 5)
|
||||
};
|
||||
FlyOver cargo = FlyOverUtility.CreateCargoFlyOver(
|
||||
map: Find.CurrentMap,
|
||||
cargoItems: cargoItems,
|
||||
startEdge: Rot4.North,
|
||||
speed: 0.8f
|
||||
);
|
||||
}
|
||||
// 3. 侦察飞越
|
||||
public void CreateScoutFlyOverExample()
|
||||
{
|
||||
FlyOver scout = FlyOverUtility.CreateScoutFlyOver(
|
||||
map: Find.CurrentMap,
|
||||
startEdge: Rot4.South,
|
||||
endEdge: Rot4.North
|
||||
);
|
||||
}
|
||||
// 4. 轰炸飞越
|
||||
public void CreateBombingRunExample()
|
||||
{
|
||||
IntVec3 target = new IntVec3(50, 0, 50); // 目标坐标
|
||||
|
||||
FlyOver bomber = FlyOverUtility.CreateBombingFlyOver(
|
||||
map: Find.CurrentMap,
|
||||
targetPosition: target,
|
||||
bombDef: ThingDefOf.Bomb,
|
||||
startEdge: Rot4.West
|
||||
);
|
||||
}
|
||||
// 5. 使用参数对象
|
||||
public void CreateWithParamsExample()
|
||||
{
|
||||
var flyOverParams = new FlyOverParams
|
||||
{
|
||||
flyOverDef = ThingDefOf.FlyOverShip,
|
||||
map = Find.CurrentMap,
|
||||
startEdge = Rot4.East,
|
||||
endEdge = Rot4.West,
|
||||
speed = 2f,
|
||||
altitude = 15f,
|
||||
contents = new List<Thing> { ThingMaker.MakeThing(ThingDefOf.Gold) },
|
||||
spawnContents = true
|
||||
};
|
||||
// 可以轻松扩展FlyOverUtility来支持参数对象
|
||||
FlyOver flyOver = FlyOverUtility.CreateFlyOverWithContents(
|
||||
flyOverParams.flyOverDef,
|
||||
flyOverParams.map,
|
||||
flyOverParams.contents,
|
||||
flyOverParams.spawnContents,
|
||||
flyOverParams.startEdge,
|
||||
flyOverParams.endEdge,
|
||||
flyOverParams.speed,
|
||||
flyOverParams.altitude
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user