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

Messages - BasedGreg

#1
Quote from: LWM on June 16, 2019, 12:01:29 AM
Sorry, which object in which part of the process?

--LWM


So, like the fermenting barrel my workbench takes an object (graphene cartridge) and converts it over time into its product (graphene sheets). The problem is that even though I have a jobdef, a workgiver, and the appropriate classes required, I can't get my pawn to fill up the barrel. When I right click on the barrel with a pawn to give a task, like you would with the fermenting barrel, no text box opens up. It's like I'm clicking nothing.
#2
Quote from: Fallcoast on June 15, 2019, 09:01:14 PM
The job not working could be a few things.  There needs to be a JobDriver class and WorkGiverDefs+JobDefs in XML too.  If the defs aren't there I don't think the game is aware that it can assign that job to pawns.  Do you get a menu when right clicking the building with a pawn selected?

This was it. Didn't even know about the jobDef. Thanks a bunch!

Unfortunately, even after having added a jobGiver class and a jobDef, it still doesn't work. I do call the class correctly so that's not the problem. For reference what happens is that the object is placed down but when I right click on it no text box opens of any kind.
#3
Quote from: Fallcoast on June 13, 2019, 03:02:37 AM
To add to what LWM already posted. 

It sounds to me like your project might have been created as a '.NET Standard' project instead of a '.NET Framework' project.  If your project's target framework is '.NET Standard 2.0', that's what happened.  The naming is confusing and its an easy mistake to make.  I think the simplest fix is to create a new .NET Framework project and copy your code there.

Graphene isn't available in ThingDefOf because Graphene isn't in the base game.  You can add your own ThingDefOf class for your mod like:

[DefOf]
public class AdvancedPrinter_ThingDefOf
{
    public static ThingDef Graphene;  //This needs to match the def Name in XML
    //Any other mod ThingDefs can be added to this class
    //...
}

Then in your code use that class instead of ThingDefOf to reference Graphene.

Thing thing = ThingMaker.MakeThing(AdvancedPrinter_ThingDefOf.Graphene);


Yeah, took me a little longer than I'd like to admit to figure out I was using a .NET standard instead of a .NET Framework hahah

Also, after using iLSpy and poking around in the dlls I managed to figure that out. I now no longer get errors! Except now the building still won't work. It's in the game and I've made a custom workgiver class (based on the fermenting barrel), but my test pawn can't load in the cartridges or really interact with the object at all. It just sits there like a glorified end table, except less useful.
#4
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;
                    }
                };
            }
        }
    }
}

#5
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!

#6
Help / Re: Damage Def Help
June 01, 2019, 07:14:18 PM
Thank you so much for pointing that out. After tinkering around with code for a bit I managed to get the game to load without an error code. But now I seem to have run into a very strange effect. Whenever I try to melee attack with the revolver, the pawn just drops it wherever they are and goes to punch their opponent to death, inevitably dying in the process.

:/

So I have no idea what to do with that. Any suggestions?
#7
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.