Add backpacks Harmony and improve rendering

Initialize Harmony for backpacks and refactor backpack rendering: add BackpacksHarmony static constructor, rename and cache graphic field, switch to Graphic_Multi/MatAt, and draw backpacks per-facing using pawn.DrawPos with configurable Vector3 offsets (north/south/east and mirrored west). Update the Harmony patch target to PawnRenderUtility.DrawEquipmentAndApparelExtras and adjust mesh selection/rotation. Also remove an empty PostExposeData and add default offset values. Project files updated to disable debug symbols for FCP_Backpacks and FCP_Lasers. Additionally, laser defs were buffed (several damageAmountBase increases and lifetimeTicks extended from 100 to 300) and a minor About.xml whitespace cleanup was applied.
This commit is contained in:
RickGrymes
2026-03-01 15:18:04 -06:00
parent f598908be6
commit ac79a15bba
9 changed files with 49 additions and 48 deletions
Binary file not shown.
Binary file not shown.
@@ -17,7 +17,7 @@
</graphicData>
<projectile>
<damageDef>FCP_Damage_Laser_Burn</damageDef>
<damageAmountBase>15</damageAmountBase>
<damageAmountBase>21</damageAmountBase>
<armorPenetrationBase>2.2</armorPenetrationBase>
<speed>140</speed>
</projectile>
@@ -27,7 +27,7 @@
<beamWidthDrawScale>1.2</beamWidthDrawScale>
<beamLength>-1</beamLength>
<damageTickRate>1</damageTickRate>
<lifetimeTicks>100</lifetimeTicks>
<lifetimeTicks>300</lifetimeTicks>
<sweepRatePerTick>0</sweepRatePerTick>
<maxSweepAngle>0</maxSweepAngle>
<damageThingsAcrossBeamLine>false</damageThingsAcrossBeamLine>
@@ -55,7 +55,7 @@
</graphicData>
<projectile>
<damageDef>FCP_Damage_Laser_Burn</damageDef>
<damageAmountBase>18</damageAmountBase>
<damageAmountBase>25</damageAmountBase>
<armorPenetrationBase>1.4</armorPenetrationBase>
<speed>140</speed>
</projectile>
@@ -65,7 +65,7 @@
<beamWidthDrawScale>1.4</beamWidthDrawScale>
<beamLength>-1</beamLength>
<damageTickRate>1</damageTickRate>
<lifetimeTicks>100</lifetimeTicks>
<lifetimeTicks>300</lifetimeTicks>
<sweepRatePerTick>0</sweepRatePerTick>
<maxSweepAngle>0</maxSweepAngle>
<damageThingsAcrossBeamLine>false</damageThingsAcrossBeamLine>
@@ -93,7 +93,7 @@
</graphicData>
<projectile>
<damageDef>FCP_Damage_Laser_Burn</damageDef>
<damageAmountBase>10</damageAmountBase>
<damageAmountBase>12</damageAmountBase>
<armorPenetrationBase>2.0</armorPenetrationBase>
<speed>140</speed>
</projectile>
@@ -103,7 +103,7 @@
<beamWidthDrawScale>1.0</beamWidthDrawScale>
<beamLength>-1</beamLength>
<damageTickRate>1</damageTickRate>
<lifetimeTicks>100</lifetimeTicks>
<lifetimeTicks>300</lifetimeTicks>
<sweepRatePerTick>0</sweepRatePerTick>
<maxSweepAngle>0</maxSweepAngle>
<damageThingsAcrossBeamLine>false</damageThingsAcrossBeamLine>
@@ -131,7 +131,7 @@
</graphicData>
<projectile>
<damageDef>FCP_Damage_Laser_Burn</damageDef>
<damageAmountBase>12</damageAmountBase>
<damageAmountBase>21</damageAmountBase>
<armorPenetrationBase>2.2</armorPenetrationBase>
<speed>140</speed>
</projectile>
@@ -141,7 +141,7 @@
<beamWidthDrawScale>1.1</beamWidthDrawScale>
<beamLength>-1</beamLength>
<damageTickRate>1</damageTickRate>
<lifetimeTicks>100</lifetimeTicks>
<lifetimeTicks>300</lifetimeTicks>
<sweepRatePerTick>0</sweepRatePerTick>
<maxSweepAngle>0</maxSweepAngle>
<damageThingsAcrossBeamLine>false</damageThingsAcrossBeamLine>
-1
View File
@@ -39,5 +39,4 @@
<li>Ludeon.RimWorld.Anomaly</li>
<li>brrainz.harmony</li>
</loadAfter>
</ModMetaData>
+13
View File
@@ -0,0 +1,13 @@
using HarmonyLib;
using Verse;
namespace FCP.Core.Backpacks;
[StaticConstructorOnStartup]
public static class BackpacksHarmony
{
static BackpacksHarmony()
{
new Harmony("FCP.Core.Backpacks").PatchAll();
}
}
@@ -1,3 +1,4 @@
using UnityEngine;
using Verse;
namespace FCP.Core.Backpacks;
@@ -7,6 +8,9 @@ public class CompProperties_WeaponBackpack : CompProperties
public string backpackTexPath;
public float backpackScale = 1f;
public bool drawBackOnlyWhenDrafted = false;
public Vector3 northOffset = new Vector3(0f, 0.04f, -0.25f);
public Vector3 southOffset = new Vector3(0f, 0.04f, 0.25f);
public Vector3 eastOffset = new Vector3(0.35f, 0.04f, -0.2f);
public CompProperties_WeaponBackpack()
{
+20 -36
View File
@@ -7,7 +7,7 @@ namespace FCP.Core.Backpacks;
public class CompWeaponBackpack : ThingComp
{
private Graphic backpackGraphic;
private Graphic cachedGraphic;
public CompProperties_WeaponBackpack Props => (CompProperties_WeaponBackpack)props;
@@ -15,59 +15,43 @@ public class CompWeaponBackpack : ThingComp
{
get
{
if (backpackGraphic == null && !Props.backpackTexPath.NullOrEmpty())
if (cachedGraphic == null && !Props.backpackTexPath.NullOrEmpty())
{
backpackGraphic = GraphicDatabase.Get<Graphic_Single>(
cachedGraphic = GraphicDatabase.Get<Graphic_Multi>(
Props.backpackTexPath,
ShaderDatabase.Cutout,
Vector2.one * Props.backpackScale,
Color.white
);
}
return backpackGraphic;
return cachedGraphic;
}
}
public override void PostExposeData()
{
base.PostExposeData();
}
}
[HarmonyPatch(typeof(PawnRenderer), "DrawEquipment")]
public static class PawnRenderer_DrawEquipment_Patch
[HarmonyPatch(typeof(PawnRenderUtility), nameof(PawnRenderUtility.DrawEquipmentAndApparelExtras))]
public static class PawnRenderUtility_DrawEquipmentAndApparelExtras_Patch
{
private static readonly System.Reflection.FieldInfo pawnField = AccessTools.Field(typeof(PawnRenderer), "pawn");
public static void Postfix(PawnRenderer __instance, Vector3 rootLoc, Rot4 pawnRotation, PawnRenderFlags flags)
public static void Prefix(Pawn pawn, Vector3 drawPos, Rot4 facing, PawnRenderFlags flags)
{
if (pawnField?.GetValue(__instance) is not Pawn pawn) return;
if (pawn?.equipment?.Primary == null) return;
var comp = pawn.equipment.Primary.TryGetComp<CompWeaponBackpack>();
if (comp == null || comp.BackpackGraphic == null) return;
if (comp?.BackpackGraphic == null) return;
if (comp.Props.drawBackOnlyWhenDrafted && !pawn.Drafted) return;
// Draw for north (back) and east (side) views
if (pawnRotation != Rot4.North && pawnRotation != Rot4.East) return;
Vector3 backpackPos = pawn.DrawPos;
if (facing == Rot4.North)
backpackPos += comp.Props.northOffset;
else if (facing == Rot4.South)
backpackPos += comp.Props.southOffset;
else if (facing == Rot4.East)
backpackPos += comp.Props.eastOffset;
else // Rot4.West
backpackPos += new Vector3(-comp.Props.eastOffset.x, comp.Props.eastOffset.y, comp.Props.eastOffset.z);
Vector3 backpackLoc = rootLoc;
backpackLoc.y += 0.04f; // Slightly above pawn layer
if (pawnRotation == Rot4.North)
{
backpackLoc.z -= 0.25f; // Behind the pawn
}
else if (pawnRotation == Rot4.East)
{
backpackLoc.x += 0.2f; // To the right side
backpackLoc.z -= 0.1f; // Slightly behind
}
Mesh mesh = MeshPool.plane10;
Quaternion quat = Quaternion.AngleAxis(0f, Vector3.up);
Graphics.DrawMesh(mesh, backpackLoc, quat, comp.BackpackGraphic.MatSingle, 0);
Mesh mesh = (facing == Rot4.West) ? MeshPool.plane10Flip : MeshPool.plane10;
Graphics.DrawMesh(mesh, backpackPos, Quaternion.identity, comp.BackpackGraphic.MatAt(facing), 0);
}
}
@@ -7,5 +7,7 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<OutputPath>..\..\1.6\Assemblies</OutputPath>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
</PropertyGroup>
</Project>
+2 -3
View File
@@ -11,17 +11,16 @@
<PropertyGroup>
<OutputPath>../../1.6/Assemblies</OutputPath>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>portable</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>