Can't have different stages of moods?

Started by alleZSoyez, January 25, 2019, 02:04:06 AM

Previous topic - Next topic

alleZSoyez

So I've created a mirror object. The goal is to have it function similarly to a corpse in that if a pawn sees it, it affects their mood. The only thing is that I'm trying to make it have a different mood effect based on whether the pawn has a beauty/ugly trait. No matter what I try, I can't seem to get the different thoughts to show up in pawns with these traits. It only ever gives pawns the first stage of my thought, as if it's not even seeing that I'm checking for the beauty trait, and I'm not sure what else to try. (Disclaimer: I've never done C# before in my life and copied a lot of this from the source code...)

C#
using RimWorld;
using Verse;

namespace TatesTinyFurnitureMod
{
    //************* mirror thought
    [DefOf]
    public static class ThoughtDefOf
    {
        public static ThoughtDef SawSelfInMirror;
    }

    //************* the thought maker
    public class SawSelfInMirror : ThoughtWorker
    {
        protected override ThoughtState CurrentStateInternal(Pawn p)
        { // human?
            if (p.RaceProps.Humanlike)
            {   // can see?
                if (p.health.capacities.CapableOf(PawnCapacityDefOf.Sight))
                {   // has beauty?
                    bool b = p.story.traits.HasTrait(TraitDefOf.Beauty);
                    if (b == true)
                    {   // how much?
                        int d = p.story.traits.DegreeOfTrait(TraitDefOf.Beauty);

                        // get values for final output
                        switch (d)
                        {
                            case -2:
                                return ThoughtState.ActiveAtStage(1);
                            case -1:
                                return ThoughtState.ActiveAtStage(2);
                            case 1:
                                return ThoughtState.ActiveAtStage(3);
                            case 2:
                                return ThoughtState.ActiveAtStage(4);
                            default:
                                return ThoughtState.ActiveAtStage(0);
                        }
                    }
                    else { return ThoughtState.ActiveAtStage(0); } // doesn't have beauty trait
                }
                else { return false; } // can't see
            }
            else { return false;  } // not human
        }
    }

    //************ building class for mirror
    public class Building_Mirror : Building, IThoughtGiver
    {
        // thought giving function
        public Thought_Memory GiveObservedThought() {
            return (Thought_MemoryObservation)ThoughtMaker.MakeThought(ThoughtDefOf.SawSelfInMirror);
        } 
    }
}


XML for the thoughts
<?xml version="1.0" encoding="utf-8"?>
<Defs>
  <ThoughtDef>
    <defName>SawSelfInMirror</defName>
    <thoughtClass>Thought_MemoryObservation</thoughtClass>
    <validWhileDespawned>true</validWhileDespawned>
    <durationDays>0.25</durationDays>
    <stackLimit>1</stackLimit>
    <stages>

      <li>
        <label>saw self in mirror</label>
        <description>Hey there, good lookin'!</description>
        <baseMoodEffect>+1</baseMoodEffect>
      </li>
     
      <li>
        <label>saw self in mirror (staggeringly ugly)</label>
        <description>Wow, I'm actually repulsive.</description>
        <baseMoodEffect>-4</baseMoodEffect>
      </li>

      <li>
        <label>saw self in mirror (ugly)</label>
        <description>Yeah, I'm pretty... pretty ugly.</description>
        <baseMoodEffect>-2</baseMoodEffect>
      </li>

      <li>
        <label>saw self in mirror (pretty)</label>
        <description>I look great today!</description>
        <baseMoodEffect>+2</baseMoodEffect>
      </li>

      <li>
        <label>saw self in mirror (beautiful)</label>
        <description>All shall gaze upon my beauty!</description>
        <baseMoodEffect>+4</baseMoodEffect>
      </li>
    </stages>
  </ThoughtDef>
</Defs>

Mehni

    <thoughtClass>Thought_MemoryObservation</thoughtClass>


You've not told RimWorld to use your C# at all; the thoughtClass in your xml should be MyNamespace.MyClass.

Log.Message will verify that your C# is running. I also recommend doing a null-check for pawn.story.

alleZSoyez

Hi, thank you for responding, and I'm really sorry for the slow reply. Just got done moving to a new place yesterday.

I tried changing the thoughtClass, and it didn't do anything. I did notice however that everything within the ThoughtWorker was being totally ignored, and that the code for when a pawn sees a corpse doesn't even use a ThoughtWorker. So I tried doing it a different way and probably copied over way too much of the code. The only thing that is missing is I can't seem to figure out how to access the Pawn declared in the Thought class. I feel like this is the only way this is going to work, but it's my understanding that it's not possible to access something in an abstract class directly? Would I have to copy that entire thing over too?

It's kind of long, so the code is on pastebin this time.
C#: https://pastebin.com/Q1BMNT66
XML: https://pastebin.com/8N6U8HYt

Distman

I think you should look more into how watching artworks(sculptures) work, since corpses gives a bad mood just for being there. Also i think you are missing a ThoughtWorker class somewhere. And multiple stages of moods/thoughts work fine.

alleZSoyez

Art sculptures don't give a mood effect though, which is why I went with copying the observed corpse code. You ever walked past a mirror and catch a glimpse of yourself, and you're either like "hey, I look great" or "oh no, I look awful today"? That's what I was going for with this.

I noticed the corpses don't even use a ThoughtWorker, and it seems that things using the IThoughtGiver interface totally ignore a ThoughtWorker. So I'm not really sure how to approach this now.