Ludeon Forums

RimWorld => Mods => Help => Topic started by: Saularian on April 01, 2015, 10:06:10 AM

Title: Disease through weapon projectile
Post by: Saularian on April 01, 2015, 10:06:10 AM
As alpha 9 added the vommiting effect, I thought it would be fun if tribals could use blowing pipes with poisonous darts that have an immediate illness effect. Or even have their arrows dipped in poison (or sharp weapons that have poison added to them). As I'm slumped on how to implement a disease type to a damagetype, I was wondering if anyone else has any ideas on that or how to do it. It could probably also  be used in tear-gas grenades, as this also has a nauseating effect :)

I hope someone can help me with this, as I'm a bit lost on how to do this, if at all even possible...
Title: Re: Disease through weapon projectile
Post by: skullywag on April 01, 2015, 12:20:17 PM
Create a new damagedef that applies a new hediffstaged and make the projectile use that damagedef. Think that would work. If not ill look into it when i get home later.
Title: Re: Disease through weapon projectile
Post by: Saularian on April 01, 2015, 03:09:49 PM
Hmmm.... I think I'm doing something wrong, I'm getting a cannot apply exceprion....

https://www.dropbox.com/sc/z02mmaut36m8ebq/AAAoEGuV8Gllo7OBz1ItLiyaa

The setup for this try was using the following coding:
Bullet
<ThingDef ParentName="BaseBullet">
<defName>Bullet_AMPoison</defName>
<label>AM Poison bullet</label>
<graphicPath>Things/Projectile/ChargeLanceShot</graphicPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>MotePostLight</shaderType>
<graphicOverdraw>true</graphicOverdraw>
<projectile>
<damageDef>PoisonBullet</damageDef>
<damageAmountBase>5</damageAmountBase>
<speed>85</speed>
</projectile>
</ThingDef>

Damagedef
<DamageDef Name="LocalInjuryBase" Abstract="True">
    <workerClass>DamageWorker_AddLocalInjury</workerClass>
  </DamageDef>

<DamageDef ParentName="LocalInjuryBase">
    <defName>PoisonBullet</defName>
    <label>Electric cut</label>
<hasForcefulImpact>True</hasForcefulImpact>
    <makesBlood>True</makesBlood>
    <externalViolence>true</externalViolence>
    <battleWound>true</battleWound>
    <deathMessage>{0} has died of poison.</deathMessage>
    <hediff>Poison</hediff>
    <hediffSolid>Poison</hediffSolid>
    <harmAllLayersUntilOutside>True</harmAllLayersUntilOutside>
    <impactSoundType>Electric</impactSoundType>
    <armorCategory>Sharp</armorCategory>
  </DamageDef>


Hediffdef

<HediffDef Name="InjuryLocalBase" Abstract="True">
    <hediffClass>Hediff_InjuryLocal</hediffClass>
    <displayWound>true</displayWound>
  </HediffDef>


 
<HediffDef ParentName="InjuryLocalBase">
<defName>Poison</defName>
<label>poison</label>
<naturallyHealed>false</naturallyHealed>
<injury>
<painPerDamage>2</painPerDamage>
<oldLabel>rotten flesh</oldLabel>
<oldPainPerDamage>0.5</oldPainPerDamage>
<bleeding>1</bleeding>
<becomeOldChance>1</becomeOldChance>
      <combine>true</combine>
<destroyedLabel>rotten off</destroyedLabel>
<destroyedOutLabel>rotten away</destroyedOutLabel>
<treatedWellLabel>bandaged</treatedWellLabel>
<treatedLabel>poorly bandaged</treatedLabel>
<innerTreatedWellLabel>sutured</innerTreatedWellLabel>
<innerTreatedLabel>poorly sutured</innerTreatedLabel>
<solidTreatedWellLabel>set</solidTreatedWellLabel>
<solidTreatedLabel>poorly set</solidTreatedLabel>
</injury>
<HediffClass>Hediff_Staged</HediffClass>
<stagedProps>
      <sendLetterWhenDiscovered>true</sendLetterWhenDiscovered>
      <treatmentDuration>20000</treatmentDuration>
      <immunityPerDay>-0.2</immunityPerDay>
      <immunityPerDaySick>0.31</immunityPerDaySick>
      <severityPerDay>0.13</severityPerDay>
      <severityPerDayImmune>-0.1</severityPerDayImmune>
      <severityPerDayTreatedOffset>-0.08</severityPerDayTreatedOffset>
      <severityStages>
        <li>
          <label>minor</label>
          <modifiers>
            <offsetPain>0.05</offsetPain>
          </modifiers>
        </li>
        <li>
          <fromSeverity>0.1</fromSeverity>
          <label>major</label>
          <modifiers>
            <offsetPain>0.08</offsetPain>
          </modifiers>
        </li>
        <li>
          <fromSeverity>0.235</fromSeverity>
          <label>extreme</label>
          <isLifeThreatening>true</isLifeThreatening>
          <modifiers>
            <offsetPain>0.12</offsetPain>
            <actMods>
              <li>
                <activity>Consciousness</activity>
                <offset>-0.05</offset>
              </li>
            </actMods>
          </modifiers>
        </li>
        <li>
          <fromSeverity>0.26</fromSeverity>
          <label>extreme</label>
          <isLifeThreatening>true</isLifeThreatening>
          <modifiers>
            <offsetPain>0.85</offsetPain>
            <actMods>
              <li>
                <activity>Consciousness</activity>
                <setMax>0.1</setMax>
              </li>
              <li>
                <activity>Breathing</activity>
                <offset>-0.05</offset>
              </li>
            </actMods>
          </modifiers>
        </li>
        <li>
          <fromSeverity>0.3</fromSeverity>
          <label>extreme</label>
          <modifiers>
            <actMods>
              <li>
                <activity>Consciousness</activity>
                <setMax>0</setMax>
              </li>
            </actMods>
          </modifiers>
        </li>
      </severityStages>
    </stagedProps>
  </HediffDef>


So something is amiss, as it seems I'm trying to apply something onto the whole body, but it can't as it is treated as a local injury...

Or I'm just messing something up that is quite obvious but easily overlooked by me :P
Title: Re: Disease through weapon projectile
Post by: skullywag on April 01, 2015, 03:44:51 PM
hediff_staged not localinjury, check hediffs_misc.xml in core for the crypto sickness hediff, it might help.
Title: Re: Disease through weapon projectile
Post by: Saularian on April 01, 2015, 05:21:24 PM
Well, that was actually one of the first things I've tried,

<HediffDef Name="DiseaseBase" Abstract="True">
    <hediffClass>Hediff_Staged</hediffClass>
    <naturallyHealed>false</naturallyHealed>
    <defaultLabelColor>(0.8, 0.8, 0.35)</defaultLabelColor>
  </HediffDef>

<HediffDef ParentName="DiseaseBase">
    <defName>Poison</defName>
    <label>poison</label>
    <disappearsAfterTicks>5000</disappearsAfterTicks>
    <stagedProps>
      <treatable>false</treatable>
      <severityStages>
        <li>
          <vomitFrequency>0.4</vomitFrequency>
          <modifiers>
            <actMods>
              <li>
                <activity>Consciousness</activity>
                <setMax>0.7</setMax>
              </li>
              <li>
                <activity>Manipulation</activity>
                <setMax>0.6</setMax>
              </li>
            </actMods>
          </modifiers>
        </li>
      </severityStages>
    </stagedProps>
  </HediffDef>


But, this does not work as the worker class tries to apply a damage to a part of the body,

<workerClass>DamageWorker_AddLocalInjury</workerClass>

instead of the whole body as damageworker_Addglobalinjury does... but that workerclass is also not able to "apply" a staged effect on a pawn. Or I'm just completely unaware of a workerclass that would allow a projectile to do a damagedef that applies such an effect :(
Title: Re: Disease through weapon projectile
Post by: skullywag on April 01, 2015, 05:30:03 PM
Ive just done this but via c# (slime poison bullet in my purpleivy mod im updating), as you state the default bullet class needs to hit a bodypart so its c# or nothing im afraid.
Title: Re: Disease through weapon projectile
Post by: Saularian on April 01, 2015, 06:05:27 PM
Yeah, and explosive class also has the same problem, (no tear gas it is then... :P) it checks bodyparts instead of the body :P
I was still wondering how <infectionChance></infectionChance> can directly feedback into the <HediffDef ParentName="DiseaseBase">
    <defName>WoundInfection</defName>

As this is pretty much the idea, although a bit more drastic and severe when poison is in play. If it is possible to add a second type of wound infection, that would be applied directly on impact, it could be used in the same way, although its a little workaround.

And c#... I can read and interpret it for the most part, but writing it is a whole different ballgame :P
Title: Re: Disease through weapon projectile
Post by: skullywag on April 02, 2015, 03:08:29 AM
Ok here what we are going to do.  If you have visual studio go grab one of my weapons. Something like the railgun (it has custom projectiles) copy the  railgunDLL folder into your mod. Rename it and all files and folders where you see RailGunDLL to whatever your mods called (not required but tidier). Then open the yourmodDLL.sln file and it should open in VS. If you get this far drop me a pm and ill give you the next steps. This isnt hard trust me.
Title: Re: Disease through weapon projectile
Post by: skullywag on April 02, 2015, 03:21:19 PM
so if youve managed to set up your dll stuff heres the code i reckon will work in the class:


protected override void Impact(Thing hitThing)
        {
            if (hitThing != null)
            {
              base.Impact(hitThing);
              //If we find a pawn
              if (hitThing.def.category == EntityCategory.Pawn)
              {
                  Pawn pawn = hitThing as Pawn;
                  HediffDef poison = HediffDef.Named("YourPoisonHeDiddDefName");
                  int damageAmountBase = this.def.projectile.damageAmountBase;
  BodyPartDamageInfo value = new BodyPartDamageInfo(null, null);
                  DamageInfo dinfo = new DamageInfo(this.def.projectile.damageDef, damageAmountBase, this.launcher, this.ExactRotation.eulerAngles.y, new BodyPartDamageInfo?(value), this.equipmentDef);
          hitThing.TakeDamage(dinfo);
                  pawn.healthTracker.AddHediff(poison, null, null);
              }
  }
      }

Title: Re: Disease through weapon projectile
Post by: Saularian on April 02, 2015, 05:17:31 PM
YAY! :P

It now does what it is supposed to do :P
(http://i.imgur.com/PTRA45n.png)

but it did throw me an exception when it misses it's target  ??? And when I thought I fixed it, it throws me the exception when hitting the target (but still does the job :P)
Title: Re: Disease through weapon projectile
Post by: skullywag on April 02, 2015, 05:28:31 PM
check the code i added a if not null check. make sure you have it.
Title: Re: Disease through weapon projectile
Post by: Saularian on April 02, 2015, 06:08:40 PM
It's a null check reference...

(http://i.imgur.com/fK12Vhd.png)

I took out the parts that are not needed (the motes, the parts that added the graphical of the railgun ;) ) to see if that would fix it, but the exception stays the same
Title: Re: Disease through weapon projectile
Post by: skullywag on April 02, 2015, 06:14:34 PM
do you have the if hithing != null check as per the code posted above?

paste your impact method here.
Title: Re: Disease through weapon projectile
Post by: Saularian on April 02, 2015, 06:52:24 PM
The only thing that made VS not build the solution was equipmentDef, that had to be changed to just equipment.

public class Projectile_SicknessBullet : Bullet
    {
        protected override void Impact(Thing hitThing)
        {
            if (hitThing != null)
            {
                base.Impact(hitThing);
                //If we find a pawn
                if (hitThing.def.category == EntityCategory.Pawn)
                {
                    Pawn pawn = hitThing as Pawn;
                    HediffDef poison = HediffDef.Named("ExtremeNausea");
                    int damageAmountBase = this.def.projectile.damageAmountBase;
                    BodyPartDamageInfo value = new BodyPartDamageInfo(null, null);
                    DamageInfo dinfo = new DamageInfo(this.def.projectile.damageDef, damageAmountBase, this.launcher,
                        this.ExactRotation.eulerAngles.y, new BodyPartDamageInfo?(value), this.equipment);
                    hitThing.TakeDamage(dinfo);
                    pawn.healthTracker.AddHediff(poison, null, null);
                    {
                        Messages.Message(pawn.Name.first + " " + pawn.Name.last + " was poisoned.", MessageSound.Negative);
                    }
                }


I think I'm missing something... Probably the part where it hit somthing other than a pawn :P
Title: Re: Disease through weapon projectile
Post by: skullywag on April 02, 2015, 07:26:26 PM
try moving the base.impact outside that check?
Title: Re: Disease through weapon projectile
Post by: Saularian on April 02, 2015, 07:43:26 PM
up or down? or I'll just try both :p ;)

Edit:

if (hitThing != null)
         base.Impact(hitThing);
         //If we find a pawn
         if (hitThing.def.category == EntityCategory.Pawn)


Makes the dev log very unhappy on a miss :(
Title: Re: Disease through weapon projectile
Post by: skullywag on April 03, 2015, 02:29:27 PM
heres my flaregun for example:


  protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);
            if (hitThing != null)
            {
                hitThing.TryAttachFire(0.3f);
                GenSpawn.Spawn(ThingDef.Named("Puddle_Fuel"), base.Position);
                FireUtility.TryStartFireIn(base.Position, 0.2f);
            }
            else
            {
                GenSpawn.Spawn(ThingDef.Named("FlareDeployed"), this.Position);
            }
            MoteThrower.ThrowStatic(this.Position, ThingDefOf.Mote_ShotFlash, 6f);
            MoteThrower.ThrowMicroSparks(base.Position.ToVector3Shifted());
        }
Title: Re: Disease through weapon projectile
Post by: mrofa on April 03, 2015, 03:22:00 PM

            if (hitThing != null && hitThing.Faction.def.humanoidFaction)
            {
                hitThing.healthTracker.AddHediff(HediffDefOf.Malaria, hitThing.RaceProps.body.corePart);
            }


Hope it helps
Title: Re: Disease through weapon projectile
Post by: Jimyoda on April 03, 2015, 03:34:22 PM
Great idea and good luck with it. Will the poisoning require medicine, to simulate antidote, before it dissipates or just bedrest and/or medical treatment (with no medicine)?  Once you've nailed this, would it mean that your code would make it easy to make cobras poisonous? Sorry that I can only give questions, not coding help.
Title: Re: Disease through weapon projectile
Post by: Saularian on April 03, 2015, 07:58:36 PM
:D had it working yesterday before I went to sleep.

added
}
                else
                {
                    if (assignedMissTarget != null)
                        MoteThrower.ThrowStatic(this.Position, ThingDefOf.Mote_ShotHit_Dirt, 1f);
                }


to the code, and it didn't throw any exceptions at me, but still needs some thorough testing though and havent had much time for it today.

@mrofa:
Thanks, I'll keep that handy if the code still seems broken (or still a bit wonky) or 'll use it for the melee part

@Jimyoda:
Diseases can affect different activities, different severities and can be treatable or untreatable or naturally healed over time. To make cobra's poisonous would probably need something pawn specific (like the zombie infection in the zombie apoc mod) but it should be possible. And no problem, even questions help, they get me thinking about possible solutions :)

But for now I'll be testing if the projectile doesn't hit me with a big red dev log.
Title: Re: Disease through weapon projectile
Post by: mrofa on April 05, 2015, 12:50:22 PM
So i got a question, i did the infection bullet but i cant get stull like plague,malaria and flue to work on it, everything else works on it. I also cant add this diseases thrugh debug tool, got any idea why ?
Title: Re: Disease through weapon projectile
Post by: skullywag on April 05, 2015, 12:59:47 PM
ive never been able to add diseases on debug tool, so id ignore that. You are probably missing the  hediffcomp_treatable that you need with diseases that arent just simple globals.
Title: Re: Disease through weapon projectile
Post by: mrofa on April 05, 2015, 01:13:04 PM
I did added wound infection which act as diesese, it works properly, other diseses dont work, i was preety sure that it might be map releated, so i tested  maps with diffrent biomes but it didnt work :/
Title: Re: Disease through weapon projectile
Post by: skullywag on April 05, 2015, 01:34:49 PM
hmm theres nothing in the defs that states it should be done any differently to infections. Ill give it a go and see what happens my end.
Title: Re: Disease through weapon projectile
Post by: skullywag on April 05, 2015, 01:46:36 PM
Can confirm the code fires but the hediff does not apply, checking how core does it a sec.

cant do it via the hediff maker either...how weird.
Title: Re: Disease through weapon projectile
Post by: Saularian on April 05, 2015, 05:26:30 PM
It seems it only takes a disease defined in the misc hediffs, but it does everything you define in it.
It works pretty fine on humans, the fix with missing a target was probably solved by having the bullet never land on a miss  :o not the most sophisticated fix, but was actually the quickest thing I could think of.

Although it's not intended to be used on animals, I tested that and although it does make em sick, it also throws me an exception... got a bunch of muffalo's now vommiting all over, but I don't think the game likes it very much. I'll look into that some more later.

At the moment I'm looking to implement it on an explosive, to make it AoE appliable, and to be used as a crowd control weapon :P