Limited Charges - KonradHeinser/EBSGFramework GitHub Wiki
This comp allows you to make any type of equippable item that gives an ability when equipped that has a limited number of uses. While it is possible to link them to vanilla abilities (as both examples will show later), it's generally recommended that each equipment has its own unique AbilityDef to reference to minimize the risk of weird interactions:
<comps>
<li Class="EBSGFramework.CompProperties_AbilityLimitedCharges">
<abilityDef>InsertAbilityDefNameHere</abilityDef>
</li>
</comps>
These are the options available within the comp:
- maxCharges : Default (1) : How many charges to give the equipment. If the abilityDef has the Reloadable Abilities comp, both limits are recorded separately, with that comp handling most of the ammo related stuff.
- If ammo is supposed to be the only limiter, leave maxCharges at 1 and give the ability a cooldown (I recommend 60 ticks to be safe)
- destroyAfterLast : Default (True) : Destroys the item as soon as the last charge is gone
- spawnOnFinalUse : A ThingDef to spawn when the final charge is used
- spawnStuffing : The ThingDef to use for stuffing the new item. This is only needed if the item with this comp doesn't have a stuffing, or if you want to override that stuffing with a static one
- spawnCount : Default (1) : How many of the spawnOnFinalUse to spawn
- effecterOnFinalUse : An EffecterDef to create when the final charge is used
- effecterTicks : Default (0) : If greater than 0, sets the effecter to last this many ticks
- filthOnFinalUse : Filth to create below/around the pawn when the final charge is used
- filthCount : Default (1) : How many of the filth to try to make
- chargeNoun : Default (charge) : The label for the charges. This only affects the stats panel and inspect panel on the equipment, but not the ability tooltip itself as that is handled by the ability (and in a way that made it too annoying to want to replace it)
- showAmmo : Default (False) : If your ability focuses on using the Reloadable Abilities to restrict casting instead of normal charges and cooldown stuff, set this to True to replace the values shown in the equipment to use ammo instead of charges. chargeNoun will still be used for this, it's just changing what value is shown
- hideCharges : Default (False) : If you don't want the equipment to show the charges/ammo remaining in its stats screen and inspection block, set this to True. It won't do anything for the ability though for the same reason that chargeNoun doesn't change that display
- saveCooldown : Default (True) : While True, the comp will try to ensure that the cooldown of the ability is not reset when the equipment is put down and picked back up. You can set this to False if you do intend for the cooldown to reset each time
Important Note: This will not change the costs of the ability, so if the ability has a cost like heat gain or hemogen, it will still require it. This also won't overwrite cooldowns, so that must still be set in the AbilityDef. It will overwrite charges though, so if you want to set the ability charges, you must do it with the maxCharges in this comp rather than the charges node in the AbilityDef.
This example is a cheap variation of the Anomaly Hellcat Rifle. Much like the normal hellcat rifle, it can spew fire, but after 3 uses it turns to ash. Not that because it is inheriting from a gun parent, it needs to have Inherit="False" on its comps so it can set a new equippable comp (this one)
<ThingDef ParentName="BaseHumanMakeableGun">
<defName>Gun_UnstableHellcatRifle</defName>
<label>unstable hellcat rifle</label>
<description>A variation of the hellcat rifle that turns to ash when its burner is used three times, and has far worse accuracy than the original.</description>
<graphicData>
<texPath>Things/Item/Equipment/WeaponRanged/HellcatRifle</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<soundInteract>Interact_Rifle</soundInteract>
<recipeMaker>
<researchPrerequisite>BioferriteIgnition</researchPrerequisite>
<skillRequirements>
<Crafting>6</Crafting>
</skillRequirements>
<displayPriority>60</displayPriority>
<recipeUsers Inherit="false">
<li>BioferriteShaper</li>
</recipeUsers>
</recipeMaker>
<thingSetMakerTags><li>RewardStandardQualitySuper</li></thingSetMakerTags>
<statBases>
<WorkToMake>40000</WorkToMake>
<Mass>3.5</Mass>
<AccuracyTouch>0.40</AccuracyTouch>
<AccuracyShort>0.50</AccuracyShort>
<AccuracyMedium>0.55</AccuracyMedium>
<AccuracyLong>0.50</AccuracyLong>
<RangedWeapon_Cooldown>1.70</RangedWeapon_Cooldown>
<Flammability>0.7</Flammability>
</statBases>
<costList>
<Steel>60</Steel>
<Bioferrite>5</Bioferrite>
<ComponentIndustrial>3</ComponentIndustrial>
</costList>
<verbs>
<li>
<verbClass>Verb_Shoot</verbClass>
<hasStandardCommand>true</hasStandardCommand>
<defaultProjectile>Bullet_HellcatRifle</defaultProjectile>
<warmupTime>1.1</warmupTime>
<range>26.9</range>
<burstShotCount>3</burstShotCount>
<ticksBetweenBurstShots>10</ticksBetweenBurstShots>
<soundCast>Shot_AssaultRifle</soundCast>
<soundCastTail>GunTail_Medium</soundCastTail>
<muzzleFlashScale>9</muzzleFlashScale>
</li>
</verbs>
<weaponTags>
<li>IndustrialGunAdvanced</li>
<li>AssaultRifle</li>
</weaponTags>
<tools>
<li>
<label>stock</label>
<capacities>
<li>Blunt</li>
</capacities>
<power>9</power>
<cooldownTime>2</cooldownTime>
</li>
<li>
<label>barrel</label>
<capacities>
<li>Blunt</li>
<li>Poke</li>
</capacities>
<power>9</power>
<cooldownTime>2</cooldownTime>
</li>
</tools>
<comps>
<li Class="EBSGFramework.CompProperties_AbilityLimitedCharges">
<abilityDef>HellcatBurner</abilityDef>
<maxCharges>3</maxCharges>
<chargeNoun>burner charge</chargeNoun>
<filthOnFinalUse>Filth_Ash</filthOnFinalUse>
<filthCount>3</filthCount>
</li>
</comps>
</ThingDef>
This example allows a pawn to turn themselves invisible once, afterwhich the cape turns into a mundane version of itself. Because the ability in question is still subject to things like entropy costs, this equipment uses the Anomaly version of invisibility instead of the psycast version to avoid requiring the wearer have a psylink:
<ThingDef ParentName="ApparelMakeableBase">
<defName>Apparel_InvisibilityCape</defName>
<label>invisibility cape</label>
<description>A cape that can be used once to turn invisible for a time before becoming a mundane cape.</description>
<possessionCount>1</possessionCount>
<graphicData>
<texPath>Things/Pawn/Humanlike/Apparel/Cape/Cape</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>1.05</drawSize>
</graphicData>
<costStuffCount>80</costStuffCount>
<stuffCategories>
<li>Fabric</li>
<li>Leathery</li>
</stuffCategories>
<thingCategories>
<li>ApparelNoble</li>
</thingCategories>
<statBases>
<MaxHitPoints>200</MaxHitPoints>
<WorkToMake>16000</WorkToMake>
<Mass>2</Mass>
<StuffEffectMultiplierArmor>0.3</StuffEffectMultiplierArmor>
<StuffEffectMultiplierInsulation_Cold>0.60</StuffEffectMultiplierInsulation_Cold>
<StuffEffectMultiplierInsulation_Heat>0.85</StuffEffectMultiplierInsulation_Heat>
<EquipDelay>3</EquipDelay>
</statBases>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Neck</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<wornGraphicPath>Things/Pawn/Humanlike/Apparel/Cape/Cape</wornGraphicPath>
<canBeDesiredForIdeo>false</canBeDesiredForIdeo>
<canBeGeneratedToSatisfyWarmth>false</canBeGeneratedToSatisfyWarmth>
<canBeGeneratedToSatisfyToxicEnvironmentResistance>false</canBeGeneratedToSatisfyToxicEnvironmentResistance>
<shellRenderedBehindHead>true</shellRenderedBehindHead>
<layers>
<li>Shell</li>
</layers>
<tags>
<li>Cape</li>
<li>Royal</li>
<li>RoyalTier2</li>
<li>RoyalTier5</li>
</tags>
</apparel>
<colorGenerator Class="ColorGenerator_StandardApparel" />
<recipeMaker>
<displayPriority>235</displayPriority>
</recipeMaker>
<comps>
<li Class="EBSGFramework.CompProperties_AbilityLimitedCharges">
<abilityDef>InvisibilityCape</abilityDef>
<spawnOnFinalUse>Apparel_Cape</spawnOnFinalUse>
</li>
</comps>
</ThingDef>
<AbilityDef>
<defName>InvisibilityCape</defName>
<label>invisibility</label>
<description>Vanish for a short time.</description>
<cooldownTicksRange>60</cooldownTicksRange>
<iconPath>UI/Abilities/Invisibility</iconPath>
<writeCombatLog>True</writeCombatLog>
<hotKey>Misc12</hotKey>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
<targetRequired>False</targetRequired>
<statBases>
<Ability_Duration>15</Ability_Duration>
</statBases>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<warmupTime>1</warmupTime>
<range>0.9</range>
<onlyManualCast>True</onlyManualCast>
<targetParams>
<canTargetSelf>True</canTargetSelf>
</targetParams>
</verbProperties>
<comps>
<li Class="CompProperties_AbilityGiveHediff">
<compClass>CompAbilityEffect_GiveHediff</compClass>
<hediffDef>PsychicInvisibility</hediffDef>
<psychic>True</psychic>
</li>
<li Class="CompProperties_AbilityFleckOnTarget">
<fleckDef>PsycastPsychicEffect</fleckDef>
</li>
</comps>
</AbilityDef>
This final example uses Reloadable Abilities to give an ability that requires ammunition. It's just a variation of the invisibility cape from before with the extra stuff added on:
<ThingDef ParentName="ApparelMakeableBase">
<defName>Apparel_InvisibilityCape</defName>
<label>invisibility cape</label>
<description>A cape that can be used once to turn invisible for a time up to 10 times before it needs splashed with chemfuel. They can't see you if you're on fire.</description>
<possessionCount>1</possessionCount>
<graphicData>
<texPath>Things/Pawn/Humanlike/Apparel/Cape/Cape</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>1.05</drawSize>
</graphicData>
<costStuffCount>80</costStuffCount>
<stuffCategories>
<li>Fabric</li>
<li>Leathery</li>
</stuffCategories>
<thingCategories>
<li>ApparelNoble</li>
</thingCategories>
<statBases>
<MaxHitPoints>200</MaxHitPoints>
<WorkToMake>16000</WorkToMake>
<Mass>2</Mass>
<StuffEffectMultiplierArmor>0.3</StuffEffectMultiplierArmor>
<StuffEffectMultiplierInsulation_Cold>0.60</StuffEffectMultiplierInsulation_Cold>
<StuffEffectMultiplierInsulation_Heat>0.85</StuffEffectMultiplierInsulation_Heat>
<EquipDelay>3</EquipDelay>
</statBases>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Neck</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<wornGraphicPath>Things/Pawn/Humanlike/Apparel/Cape/Cape</wornGraphicPath>
<canBeDesiredForIdeo>false</canBeDesiredForIdeo>
<canBeGeneratedToSatisfyWarmth>false</canBeGeneratedToSatisfyWarmth>
<canBeGeneratedToSatisfyToxicEnvironmentResistance>false</canBeGeneratedToSatisfyToxicEnvironmentResistance>
<shellRenderedBehindHead>true</shellRenderedBehindHead>
<layers>
<li>Shell</li>
</layers>
<tags>
<li>Cape</li>
<li>Royal</li>
<li>RoyalTier2</li>
<li>RoyalTier5</li>
</tags>
</apparel>
<colorGenerator Class="ColorGenerator_StandardApparel" />
<recipeMaker>
<displayPriority>235</displayPriority>
</recipeMaker>
<comps>
<li Class="EBSGFramework.CompProperties_AbilityLimitedCharges">
<abilityDef>InvisibilityCape</abilityDef>
<destroyAfterLast>False</destroyAfterLast>
<chargeNoun>Vanishings</chargeNoun>
<showAmmo>True</showAmmo>
</li>
</comps>
</ThingDef>
<AbilityDef>
<defName>InvisibilityCape</defName>
<label>invisibility</label>
<description>Vanish for a short time.</description>
<cooldownTicksRange>60</cooldownTicksRange>
<iconPath>UI/Abilities/Invisibility</iconPath>
<writeCombatLog>True</writeCombatLog>
<hotKey>Misc12</hotKey>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
<targetRequired>False</targetRequired>
<statBases>
<Ability_Duration>15</Ability_Duration>
</statBases>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<warmupTime>1</warmupTime>
<range>0.9</range>
<onlyManualCast>True</onlyManualCast>
<targetParams>
<canTargetSelf>True</canTargetSelf>
</targetParams>
</verbProperties>
<comps>
<li Class="CompProperties_AbilityGiveHediff">
<compClass>CompAbilityEffect_GiveHediff</compClass>
<hediffDef>PsychicInvisibility</hediffDef>
<psychic>True</psychic>
</li>
<li Class="CompProperties_AbilityFleckOnTarget">
<fleckDef>PsycastPsychicEffect</fleckDef>
</li>
<li Class="EBSGFramework.CompProperties_AbilityReloadable">
<maxCharges>10</maxCharges>
<ammoPerCharge>10</ammoPerCharge>
<ammoDef>Chemfuel</ammoDef>
</li>
</comps>
</AbilityDef>