Adding static mote-throwing effecters to a building: help make my chair vomit

Started by panggul_mas, May 12, 2016, 03:53:22 PM

Previous topic - Next topic

panggul_mas

What would be the most straightforward way to add a static mote effect to a building? The existing mote-throwing effecters all seem to be tied to an activity (eating, constructing, crafting).

After 72 hours of failed attempts, I thought I'd ask for some help here.

1000101

That doesn't give us much to help with.

Tell us about what you have tried.  Tell us about what you have researched (ie, an existing resource that does this), what you learned from the xml and decompiled classes for what you have investigated.  Finally, show us the xml/C# code of where you are at.

Hint - Steam Geysers throw motes, start your search there.
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

panggul_mas

Well, before I start I'll say that my real goal is to make a temporary building give off sparks (the building code is ready and works fine), either using the fzzzz from an exploding turret, or some other sparking mote effect [EDIT: the sparkThrown from construction would be preferable at this point].


A Series of Unfortunate Attempts

1. The first step is always to see if you can just cut and past defs. I made a meat smoker for A12 that smoked when manned, so I started there. The smoking mote effect was triggered by <effectWorking>Cook</effectWorking> being part of a recipe. This doesn't work for a building of course, for about nine unique reasons, the most important of which is that effectWorking is defined in the Recipe class but not in the ThingDef class, so it won't be recognized. Ok, so does ThingDef have a simple mote thrower to use? lets look it up in ilspy aaaaand...nope.

2. Ok, what about a comp? Comps are great, you can just throw them in there willy-nilly and go bananas. Milk a glowing tree, store energy in a pile of hay, turn a pig on and off with a switch, whatevs. Well, there's lots of cool comps, but no generic "smoke" or "throw mote" comp. Maybe making a new comp that does this could work, but I have to believe there is another solution out there that is less "from scratch". Maybe this is the wrong approach.

3. Ok, maybe start from the end and work back - I'll look up the fzzzz-ing effect of exploding turrets and work backwards. Well the only references to burningwick(the texture used for the fzzz-ing of exploding turrets) are in OverlayDrawer, and I tried backtracking from there to find a connection to turrets so I could hopefully reconstruct how the fzzzzz is called, but no luck there.

4. Ok, back to #2, maybe a custom comp is the best bet. So I ask for help and Saint Skullywag shows me the source of one of his mods that happens to have a spark effect. So I used the only approach that was available to me, one that has worked in the past but still feels really uncomfortable, and start hacking up c# code that I only partially understand and don't get the syntax of. So now I have a custom Comp and accompanying CompProperties and applied the comp to the xml def of the building i want to sparkle.

Here's the custom comp:
using Verse;
using UnityEngine;
using System.Collections.Generic;
using Random = System.Random;

namespace XXXXX
{
    public class CompFlareDeployedSparkle : ThingComp
    {
        public Effecter sparks = null; // Global effects variable
        public int cellsDamaged = 0;
        public IntVec3 sparker; // A random cell in the occupied list
        public IEnumerable<IntVec3> occupiedCells = null; // List of cells the drop pod occupies
        public List<IntVec3> damagedCells = new List<IntVec3>(); // list of smoke and spark generators

        public CompProperties_FlareDeployedSparkle Props
        {   
            get
            {
                return (CompProperties_FlareDeployedSparkle)this.props;
            }
        }
        public override void PostSpawnSetup()
        {
            // Do base setup
            base.PostSpawnSetup();
            // Setup list of cells the drop ship occupies
            occupiedCells = GenAdj.CellsOccupiedBy(parent);
            // Pick a random cell for mote usage
            sparker = occupiedCells.RandomElement<IntVec3>();
           
        }
        public override void PostExposeData()
        {
            // Base date to save
            base.PostExposeData();
        }
        public override void CompTick()
        {
            base.CompTick();
            foreach (IntVec3 currentCell in damagedCells)
            {
               
                if (Props.spark)
                {
                    // Setup a new spark effect
                    sparks = new Effecter(DefDatabase<EffecterDef>.GetNamed("FlareSparkle"));
                    // If we have a spark effecter
                    if (sparks != null)
                    {
                        if (Rand.Value < Props.sparkChance)
                        {
                            // Continue effect
                            sparks.EffectTick(parent.Position, parent);
                            sparks.Cleanup();
                            sparks = null;
                        }
                    }
                }
            }
        }
       
       
    }
}


the compProperties:
using System;
using Verse;
using RimWorld;

namespace XXXXX
{
    public class CompProperties_FlareDeployedSparkle : CompProperties
    {
        public bool spark;
        public float sparkChance;
       
        public CompProperties_FlareDeployedSparkle()
        {
            this.compClass = typeof(CompFlareDeployedSparkle);
        }
    }
}


and the buildingDef trying to call the comp:


     <ThingDef ParentName="BuildingBase">
<defName>Flare_Deployed</defName>
<label>Flare Glower</label>
<thingClass>XXXXX.Deployed_Flare_Glower</thingClass>
<graphicData>   
  <texPath>Things/Projectile/FlareDeployedInvis</texPath>
  <graphicClass>Graphic_Single</graphicClass>
</graphicData>
     <building>
      <isEdifice>false</isEdifice>
     </building>
     <altitudeLayer>Item</altitudeLayer>
     <passability>PassThroughOnly</passability>
<useHitPoints>false</useHitPoints>
<comps>
  <li Class="CompProperties_Glower">
<glowRadius>14</glowRadius>
<glowColor>(150,27,27,0)</glowColor>


  </li>
      <li Class="XXXXX.CompProperties_FlareDeployedSparkle">
        <compClass>XXXXX.CompFlareDeployedSparkle</compClass>
        <spark>true</spark>
        <sparkChance>0.99</sparkChance>
      </li>
   

</comps>
<selectable>false</selectable>
<tickerType>Normal</tickerType>
<description></description>
</ThingDef>


and finally the effecter:
<EffecterDef>
    <defName>FlareSparkle</defName>
    <children>
      <li>
        <subEffecterClass>SubEffecter_Sustainer</subEffecterClass>
        <soundDef>Sustainer_ElectricShort</soundDef>
      </li>
      <li>
        <subEffecterClass>SubEffecter_SprayerChance</subEffecterClass>
        <moteDef>Mote_DustPuff</moteDef>
        <ChancePerTick>0.035</ChancePerTick>
        <startScale>
          <min>0.3</min>
          <max>0.5</max>
        </startScale>
        <rotationRate>
          <min>-1</min>
          <max>1</max>
        </rotationRate>
        <velocity>
          <min>0.01</min>
          <max>0.03</max>
        </velocity>
      </li>
      <li>
        <subEffecterClass>SubEffecter_SprayerChance</subEffecterClass>
        <moteDef>Mote_SparkFlash</moteDef>
        <spawnLocType>BetweenTouchingCells</spawnLocType>
        <positionLerpFactor>0.05</positionLerpFactor>
        <ChancePerTick>0.05</ChancePerTick>
        <startScale>
          <min>1.5</min>
          <max>1.9</max>
        </startScale>
      </li>
      <li>
        <subEffecterClass>SubEffecter_SprayerChance</subEffecterClass>
        <moteDef>Mote_SparkThrown</moteDef>
        <spawnLocType>BetweenTouchingCells</spawnLocType>
        <positionLerpFactor>0.05</positionLerpFactor>
        <ChancePerTick>0.01</ChancePerTick>
        <StartScale>
          <min>0.24</min>
          <max>0.34</max>
        </StartScale>
        <airTicks>
          <min>1</min>
          <max>3</max>
        </airTicks>
        <rotationRate>
          <min>-1</min>
          <max>1</max>
        </rotationRate>
        <velocity>
          <min>0.3</min>
          <max>0.2</max>
        </velocity>
        <moveDirection>
          <min>135</min>
          <max>205</max>
        </moveDirection>
        <positionRadius>0.002</positionRadius>
      </li>
    </children>
  </EffecterDef>



The custom classes are working fine. As is, none of this creates any errors, but it also doesn't do anything. Much of this is copypasted from someone else's project, so if there is a bunch of unnecessary material in there, that's why. I anticipate the problem being some simple oversight, but I'm not sure where to look.

I checked into geysers, but it looks like the mechanic they use for throwing motes uses snowUtility, and I'm not sure I want to go in that direction.

Thanks for your time!



RawCode

you have ZERO debugging messages in your code, fix it and try again.

currently you dont know is your methods called at all or not.

panggul_mas

Quote from: RawCode on May 14, 2016, 07:46:33 AM
you have ZERO debugging messages in your code, fix it and try again.

currently you dont know is your methods called at all or not.


Thanks for the advice RawCode. Could you suggest where/how to add the debugging messages? I know this the Mod Help forum and not the "learn the most basic shit about C#" forum, but I'm learning as I go, so any help however rudimentary would be appreciated.


1000101

Use the game debug logging.

[Verse.]Log.Message( string );

It will be sent to both the debug window and the games log file.
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

RawCode

https://en.wikipedia.org/wiki/Tracing_(software)
read carefuly and completely, walk over provided links.

Tracing is not "coding" skill, it's skill you need for IRL.
Understanding of "tracing" will help you everywhere and greatly improvide your skills.

I will explain in interactive manner:

1. You try to switch light on (inside your own home) and nothing happens, what will you do?
2. What will you do next?
3. What will you do if your next (step 2) action had no effect?

answer provided questions and i will explain next part.