Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - BasedGreg

#1
So my ambition has quickly escalated since I started modding. I am now starting my first attempt at C# to create a buildingClass for a production building that functions similarly to how to fermenting barrel does, except instead of wort and beer, you turn cartridges into graphene.

I have two problems, the first is that my visual studios project is running on .NET framework 2.0 and I have been completely unable to get anything past 2.0 to work. Will this work fine? If not how do I install other frameworks?

My second problem is that I have only one error. 'ThingDefOf' does not contain a definition for 'Graphene'.
I haven't the faintest clue how to resolve this. The code for the fermenting barrel also doesn't have a definiton for beer yet that seems to work fine. What do?

Here's my code if you're willing to look through. I appreciate any and all help.

using RimWorld;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using Verse;

namespace Building_AdvancedPrinter
{
    [StaticConstructorOnStartup]
    public class Building_AdvancedPrinter : Building
    {
        private int GrapheneCartridgeCount;

        private float progressInt;

        private Material barFilledCachedMat;

        public const int MaxGrapheneCartridgeCapacity = 10;

        private const int BaseReactionDuration = 120000;

        public const float MinIdealTemperature = -125f;

        private static readonly Vector2 BarSize = new Vector2(0.55f, 0.1f);

        private static readonly Color BarZeroProgressColor = new Color(0.4f, 0.27f, 0.22f);

        private static readonly Color BarFermentedColor = new Color(0.6f, 0.93f, 0.96f);

        private static readonly Material BarUnfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.3f, 0.3f, 0.3f));

        public float Progress
        {
            get
            {
                return progressInt;
            }
            set
            {
                if (value != progressInt)
                {
                    progressInt = value;
                    barFilledCachedMat = null;
                }
            }
        }

        private Material BarFilledMat
        {
            get
            {
                if (barFilledCachedMat == null)
                {
                    barFilledCachedMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.Lerp(BarZeroProgressColor, BarFermentedColor, Progress));
                }
                return barFilledCachedMat;
            }
        }

        public int SpaceLeftForGrapheneCartridge
        {
            get
            {
                if (Fermented)
                {
                    return 0;
                }
                return 10 - GrapheneCartridgeCount;
            }
        }

        private bool Empty => GrapheneCartridgeCount <= 0;

        public bool Fermented => !Empty && Progress >= 1f;

        private float CurrentTempProgressSpeedFactor
        {
            get
            {
                CompProperties_TemperatureRuinable compProperties = def.GetCompProperties<CompProperties_TemperatureRuinable>();
                float ambientTemperature = base.AmbientTemperature;
                if (ambientTemperature < compProperties.minSafeTemperature)
                {
                    return 0.1f;
                }
                if (ambientTemperature < 7f)
                {
                    return GenMath.LerpDouble(compProperties.minSafeTemperature, 7f, 0.1f, 1f, ambientTemperature);
                }
                return 1f;
            }
        }

        private float ProgressPerTickAtCurrentTemp => 2.77777781E-06f * CurrentTempProgressSpeedFactor;

        private int EstimatedTicksLeft => Mathf.Max(Mathf.RoundToInt((1f - Progress) / ProgressPerTickAtCurrentTemp), 0);

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_Values.Look(ref GrapheneCartridgeCount, "GraphiteCount", 0);
            Scribe_Values.Look(ref progressInt, "progress", 0f);
        }

        public override void TickRare()
        {
            base.TickRare();
            if (!Empty)
            {
                Progress = Mathf.Min(Progress + 125f * ProgressPerTickAtCurrentTemp, 1f);
            }
        }

        public void AddGraphite(int count)
        {
            GetComp<CompTemperatureRuinable>().Reset();
            if (Fermented)
            {
                Log.Warning("Tried to add a graphene cartridge to a depositor filled with graphene sheets. Colonists should remove the graphene sheets first.");
                return;
            }
            int num = Mathf.Min(count, 10 - GrapheneCartridgeCount);
            if (num > 0)
            {
                Progress = GenMath.WeightedAverage(0f, num, Progress, GrapheneCartridgeCount);
                GrapheneCartridgeCount += num;
            }
        }

        protected override void ReceiveCompSignal(string signal)
        {
            if (signal == "RuinedByTemperature")
            {
                Reset();
            }
        }

        private void Reset()
        {
            GrapheneCartridgeCount = 0;
            Progress = 0f;
        }

        public void AddGrapheneCartridge(Thing GrapheneCartridge)
        {
            int num = Mathf.Min(GrapheneCartridge.stackCount, 10 - GrapheneCartridgeCount);
            if (num > 0)
            {
                AddGraphite(num);
                GrapheneCartridge.SplitOff(num).Destroy();
            }
        }

        public override string GetInspectString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(base.GetInspectString());
            if (stringBuilder.Length != 0)
            {
                stringBuilder.AppendLine();
            }
            CompTemperatureRuinable comp = GetComp<CompTemperatureRuinable>();
            if (!Empty && !comp.Ruined)
            {
                if (Fermented)
                {
                    stringBuilder.AppendLine("ContainsGraphene".Translate(GrapheneCartridgeCount, 10));
                }
                else
                {
                    stringBuilder.AppendLine("ContainsGrapheneCartridge".Translate(GrapheneCartridgeCount, 10));
                }
            }
            if (!Empty)
            {
                if (Fermented)
                {
                    stringBuilder.AppendLine("Complete".Translate());
                }
                else
                {
                    stringBuilder.AppendLine("ReactionProgress".Translate(Progress.ToStringPercent(), EstimatedTicksLeft.ToStringTicksToPeriod()));
                    if (CurrentTempProgressSpeedFactor != 1f)
                    {
                        stringBuilder.AppendLine("GrapheneVatOutOfIdealTemperature".Translate(CurrentTempProgressSpeedFactor.ToStringPercent()));
                    }
                }
            }

            stringBuilder.AppendLine("Temperature".Translate() + ": " + base.AmbientTemperature.ToStringTemperature("F0"));
            stringBuilder.AppendLine("IdealReactingTemperature".Translate() + ": " + 7f.ToStringTemperature("F0") + " ~ " + comp.Props.maxSafeTemperature.ToStringTemperature("F0"));
            return stringBuilder.ToString().TrimEndNewlines();
        }

        public Thing TakeOutGraphene()
        {
            if (!Fermented)
            {
                Log.Warning("Tried to get graphene but it's not yet complete.");
                return null;
            }
            Thing thing = ThingMaker.MakeThing(ThingDefOf.Graphene);
            thing.stackCount = GrapheneCartridgeCount;
            Reset();
            return thing;
        }

        public override void Draw()
        {
            base.Draw();
            if (!Empty)
            {
                Vector3 drawPos = DrawPos;
                drawPos.y += 3f / 64f;
                drawPos.z += 0.25f;
                GenDraw.FillableBarRequest r = default(GenDraw.FillableBarRequest);
                r.center = drawPos;
                r.size = BarSize;
                r.fillPercent = (float)GrapheneCartridgeCount / 25f;
                r.filledMat = BarFilledMat;
                r.unfilledMat = BarUnfilledMat;
                r.margin = 0.1f;
                r.rotation = Rot4.North;
                GenDraw.DrawFillableBar(r);
            }
        }

        public override IEnumerable<Gizmo> GetGizmos()
        {
            foreach (Gizmo gizmo in base.GetGizmos())
            {
                yield return gizmo;
            }
            if (Prefs.DevMode && !Empty)
            {
                yield return new Command_Action
                {
                    defaultLabel = "Debug: Set progress to 1",
                    action = delegate
                    {
                        Progress = 1f;
                    }
                };
            }
        }
    }
}

#2
Help / Custom Melee Audio
June 07, 2019, 05:58:43 AM
Hello Ludeon,
I'm current working on my most recent additon to my personal mod collection. A charge sword that in all honesty is basically just a lightsaber. I'm aware there is a lightsaber mod but I have run into framerate problems with that mod so I'm just trying to make one of my own that is also a bit more lore-friendly.


The weapon itself works just fine, but the problem I'm having is with adding custom audio to the weapon.

Here's my current code:

SoundDef:

<?xml version="1.0" encoding="utf-8"?>

<Defs>

  <SoundDef>
    <defName>Pawn_Melee_Saber_Cut</defName> 
    <context>MapOnly</context>
    <eventNames /> 
    <maxVoices>2</maxVoices> 
    <subSounds>
      <li>
        <grains>
          <li Class="AudioGrain_Folder">
            <clipFolderPath>Melee/sabercut</clipFolderPath>
          </li>
        </grains>     
        <volumeRange>
          <min>20</min>       
          <max>20</max>
        </volumeRange>     
        <pitchRange>
          <min>1</min>       
          <max>1.18353</max>
        </pitchRange>
      </li>
    </subSounds>
  </SoundDef>
 
    <SoundDef>
    <defName>Pawn_Melee_Saber_Stab</defName> 
    <context>MapOnly</context>
    <eventNames /> 
    <maxVoices>2</maxVoices> 
    <subSounds>
      <li>
        <grains>
          <li Class="AudioGrain_Folder">
            <clipFolderPath>Melee/saberstab</clipFolderPath>
          </li>
        </grains>     
        <volumeRange>
          <min>20</min>       
          <max>20</max>
        </volumeRange>     
        <pitchRange>
          <min>1</min>       
          <max>1.18353</max>
        </pitchRange>
      </li>
    </subSounds>
  </SoundDef>
 
  </Defs>


BaseDef:

<DamageDef>
    <defName>SaberStab</defName>
    <label>saberstab</label>
    <workerClass>DamageWorker_Stab</workerClass>
    <externalViolence>true</externalViolence>
    <deathMessage>{0} has been sabered to death.</deathMessage>
    <hediff>Burn</hediff>
<hediffSkin>Burn</hediffSkin>
    <hediffSolid>Burn</hediffSolid>
    <impactSoundType>Slice</impactSoundType>
    <armorCategory>Heat</armorCategory>
    <stabChanceOfForcedInternal>0.9</stabChanceOfForcedInternal>
    <overkillPctToDestroyPart>0.4~1.0</overkillPctToDestroyPart>
  </DamageDef>
 
    <DamageDef Name="CutBase">
    <defName>SaberCut</defName>
    <label>sabercut</label>
    <workerClass>DamageWorker_Cut</workerClass>
    <externalViolence>true</externalViolence>
    <deathMessage>{0} has been sabered to death.</deathMessage>
    <hediff>Burn</hediff>
    <hediffSkin>Burn</hediffSkin>
    <hediffSolid>Burn</hediffSolid>
    <harmAllLayersUntilOutside>true</harmAllLayersUntilOutside>
    <impactSoundType>Slice</impactSoundType>
    <armorCategory>Heat</armorCategory>
<stabChanceOfForcedInternal>0.8</stabChanceOfForcedInternal>
    <overkillPctToDestroyPart>0.4~1.0</overkillPctToDestroyPart>
    <cutExtraTargetsCurve>
      <points>
        <li>0, 0</li>
        <li>0.6, 1</li>
        <li>0.9, 2</li>
        <li>1, 3</li>
      </points>
    </cutExtraTargetsCurve>
    <cutCleaveBonus>1.4</cutCleaveBonus>
  </DamageDef>

  <ManeuverDef>
    <defName>SaberSlash</defName>
    <requiredCapacity>SaberCut</requiredCapacity>
    <verb>
      <verbClass>Verb_MeleeAttackDamage</verbClass>
      <meleeDamageDef>SaberCut</meleeDamageDef>
  <soundCast>Pawn_Melee_Saber_Cut</soundCast>
    </verb>
    <logEntryDef>MeleeAttack</logEntryDef>
    <combatLogRulesHit>Maneuver_Slash_MeleeHit</combatLogRulesHit>
    <combatLogRulesDeflect>Maneuver_Slash_MeleeDeflect</combatLogRulesDeflect>
    <combatLogRulesMiss>Maneuver_Slash_MeleeMiss</combatLogRulesMiss>
    <combatLogRulesDodge>Maneuver_Slash_MeleeDodge</combatLogRulesDodge>
  </ManeuverDef>

  <ManeuverDef>
    <defName>SaberStab</defName>
    <requiredCapacity>SaberStab</requiredCapacity>
    <verb>
      <verbClass>Verb_MeleeAttackDamage</verbClass>
      <meleeDamageDef>SaberStab</meleeDamageDef>
  <soundCast>Pawn_Melee_Saber_Stab</soundCast>
    </verb>
    <logEntryDef>MeleeAttack</logEntryDef>
    <combatLogRulesHit>Maneuver_Stab_MeleeHit</combatLogRulesHit>
    <combatLogRulesDeflect>Maneuver_Stab_MeleeDeflect</combatLogRulesDeflect>
    <combatLogRulesMiss>Maneuver_Stab_MeleeMiss</combatLogRulesMiss>
    <combatLogRulesDodge>Maneuver_Stab_MeleeDodge</combatLogRulesDodge>
  </ManeuverDef>
 
    <ToolCapacityDef>
    <defName>SaberStab</defName>
  </ToolCapacityDef>
 
   <ToolCapacityDef>
    <defName>SaberCut</defName>
  </ToolCapacityDef>


and WeaponDef:

<ThingDef ParentName="Greggo_BaseMeleeWeapon">
<defName>ChargeSword</defName>
<label>charge blade</label>
<description>Melee weapons were thought to be a thing of the past, but with pulse technology also came the invention of the energy sword. The weapon itself is extremely powerful, able to slice thorugh even the strongest armor and the built in gyrostablizer makes this blade feel almost weightless as one swings.</description>
<graphicData>
<texPath>Things/Melee/ChargeBlade</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<techLevel>Spacer</techLevel>
<costList>
<Plasteel>80</Plasteel>
<ComponentSpacer>5</ComponentSpacer>
</costList>
<statBases>
<WorkToMake>45000</WorkToMake>
<Mass>3.5</Mass>
</statBases>
<equippedAngleOffset>-65</equippedAngleOffset>
<tools>
<li>
<label>handle</label>
<capacities>
<li>Blunt</li>
</capacities>
<power>8</power>
<cooldownTime>1</cooldownTime>
</li>
<li>
<label>point</label>
<capacities>
<li>SaberStab</li>
</capacities>
<power>22</power>
<cooldownTime>0.8</cooldownTime>
<armorPenetration>0.7</armorPenetration>
</li>
<li>
<label>edge</label>
<capacities>
<li>SaberCut</li>
</capacities>
<power>26</power>
<cooldownTime>0.9</cooldownTime>
<armorPenetration>0.7</armorPenetration>
</li>
</tools>
<recipeMaker>
<skillRequirements>
<Crafting>8</Crafting>
</skillRequirements>
<recipeUsers Inherit="False">
<li>FabricationBench</li>
</recipeUsers>
</recipeMaker>
</ThingDef>


I have already tried having the audio file location say Sounds/Melee/(etc), and that didn't make a difference so I'm assuming that's not where my problem is. Yeah, I'm just stuck so any advice would be greatly appreciated!

#3
Help / Damage Def Help
May 31, 2019, 06:23:30 PM
Hello Ludeon,
I'm here due to the fact that I have very little idea as to what I'm doing.
I have a little personal mod I work on that adds a couple guns and melee weapons and I have run into a bit of a roadblock.

One of my recent weapons, a charge "revolver", has something that I haven't tried before. I was going to add a taser to the front of the weapon in order to amplify its melee effectiveness. I have long since given up on trying to add Stun as one of the capacities of the melee attacks and have gone on to trying to make my own damage def that works similarily to blunt damage but has an extended stun duration.

Here's what I have so far for the damage def:

<DamageDef Name="TaseBase">
    <defName>Tase</defName>
    <label>tase</label>
    <workerClass>DamageWorker_Blunt</workerClass>
    <externalViolence>true</externalViolence>
    <deathMessage>{0} has been tased to death.</deathMessage>
    <hediff>Crush</hediff>
    <hediffSkin>Bruise</hediffSkin>
    <hediffSolid>Crack</hediffSolid>
    <harmAllLayersUntilOutside>true</harmAllLayersUntilOutside>
    <impactSoundType>Blunt</impactSoundType>
    <armorCategory>Blunt</armorCategory>
    <overkillPctToDestroyPart>0.2~0.6</overkillPctToDestroyPart>
    <buildingDamageFactor>1.5</buildingDamageFactor>
    <bluntStunDuration>12.0</bluntStunDuration>
    <bluntInnerHitChance>0.4</bluntInnerHitChance>
    <bluntInnerHitDamageFractionToConvert>
      <min>0.1</min>
      <max>0.2</max>
    </bluntInnerHitDamageFractionToConvert>
    <bluntInnerHitDamageFractionToAdd>
      <min>0.2</min>
      <max>0.35</max>
    </bluntInnerHitDamageFractionToAdd>
    <bluntStunChancePerDamagePctOfCorePartToHeadCurve>
      <points>
        <li>(0.04, 0.20)</li>
        <li>(0.5, 1)</li>
      </points>
    </bluntStunChancePerDamagePctOfCorePartToHeadCurve>
    <bluntStunChancePerDamagePctOfCorePartToBodyCurve>
      <points>
        <li>(0.4, 0)</li>
        <li>(0.9, 0.15)</li>
      </points>
    </bluntStunChancePerDamagePctOfCorePartToBodyCurve>
  </DamageDef>


And here's my code for the weapon itself:

<ThingDef ParentName="BaseHumanMakeableGun">
    <defName>Gun_chargeRevolver</defName>
    <label>reducer</label>
    <description>The quickest draw in the galaxy, this spacer tier revolver uses an entire cartridge for each shot. The resulting effect is a slow yet terribly, powerful shot. The muzzle of the gun is armed with a powerful tazer for stunning opponents that get a bit too close and personal.</description>
    <graphicData>
      <texPath>Things/Ranged/Reducer</texPath>
      <graphicClass>Graphic_Single</graphicClass>
    </graphicData>
    <soundInteract>Interact_Revolver</soundInteract>
    <statBases>
      <WorkToMake>29000</WorkToMake>
      <Mass>1.6</Mass>
      <AccuracyTouch>0.81</AccuracyTouch>
      <AccuracyShort>0.78</AccuracyShort>
      <AccuracyMedium>0.62</AccuracyMedium>
      <AccuracyLong>0.53</AccuracyLong>
      <RangedWeapon_Cooldown>2.2</RangedWeapon_Cooldown>
    </statBases>
    <weaponTags>
      <li>SpacerGun</li>
      <li>Revolver</li>
    </weaponTags>
    <costList>
      <Plasteel>45</Plasteel>
      <ComponentSpacer>3</ComponentSpacer>
    </costList>
    <recipeMaker>
  <researchPrerequisite>ChargedShot</researchPrerequisite>
      <skillRequirements>
        <Crafting>9</Crafting>
      </skillRequirements>
  <recipeUsers Inherit="False">
        <li>FabricationBench</li>
      </recipeUsers>
    </recipeMaker>
    <verbs>
      <li>
        <verbClass>Verb_Shoot</verbClass>
        <hasStandardCommand>true</hasStandardCommand>
        <defaultProjectile>Bullet_chargeRevolver</defaultProjectile>
        <warmupTime>0.01</warmupTime>
        <range>30</range>
        <soundCast>Shot_ChargeRifle</soundCast>
        <soundCastTail>GunTail_Light</soundCastTail>
        <muzzleFlashScale>9</muzzleFlashScale>
      </li>
    </verbs>
    <tools>
      <li>
        <label>grip</label>
        <capacities>
          <li>Blunt</li>
        </capacities>
        <power>11</power>
        <cooldownTime>2</cooldownTime>
      </li>
      <li>
        <label>barrel</label>
        <capacities>
  <li>Tase</li>
  <li>Poke</li>
        </capacities>
<power>11</power>
        <cooldownTime>2.5</cooldownTime>
      </li>
    </tools>
  </ThingDef>


When I do this all I get is this error:

Could not resolve cross-reference to Verse.ToolCapacityDef named Tase (wanter=capacities)
Verse.Log:Error(String, Boolean)
Verse.DirectXmlCrossRefLoader:TryResolveDef(String, FailMode, Object)
Verse.WantedRefForList`1:TryResolve(FailMode)
Verse.DirectXmlCrossRefLoader:ResolveAllWantedCrossReferences(FailMode)
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__1()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__1()

Cannot call ItemFromXmlFile with resolveCrossRefs=true while loading is already in progress.
Verse.Log:Error(String, Boolean)
Verse.DirectXmlLoader:ItemFromXmlFile(String, Boolean)
RimWorld.PlayerKnowledgeDatabase:ReloadAndRebind()
RimWorld.PlayerKnowledgeDatabase:.cctor()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__1()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__1()


I have no idea what to do at this point so this is my last attempt before my dream of a charge taser revolver dies.
Halp.