General Code Help

I see. I have some bad logic somewhere. What’s the proper way to make one of these: {You’re/his}? for my illogical. Like ‘{You/he} can’t equip {that dobj/him} without it in {You’re/his} inventory.’

The logic you gave me working but it always goes to the not holding code, even though I’m holding it. On take I move it into my character: gDobj.moveInto(gActor). And I can drop it, so I know it was there.

 verify()
        {
            
            if(gDobj && gDobj.isHeldBy(gActor))
            {
                
                switch(self.classification)
                {
                        
                    case 'wpn':
                        // test if already equipped 
                        
                        foreach(local x in gActor.contents)
                        {
                        
                            if(gDobj == x)
                            {
                            
                                if(x.isEquipped)
                                {
                                    
                                    illogical('{that dobj/him} is already equipped.');
                                    
                                }else{
                                    
                                    // test if character class in wpn class
                                       
                                        if(self.classList.indexOf(gActor.charClass) == nil)
                                        {
                                            
                                            illogical('{You/he} do{es}n\'t equip
                                                        {that dobj/him}.');
                                        
                                        }
                                    
                                }
                            
                            }
                        
                        }
                    break;
                    case 'arm':
                        // test if character class in arm class
                         foreach(local x in gActor.contents)
                        {
                        
                            if(gDobj == x)
                            {
                            
                                if(x.isEquipped)
                                {
                                    
                                    illogical('{that dobj/him} is already equipped.');
                                    
                                }else{
                                    
                                    // test if character class in wpn class
                                       
                                        if(self.classList.indexOf(gActor.charClass) == nil)
                                        {
                                            
                                            illogical('{You/he} do{es}n\'t equip
                                                        {that dobj/him}.');
                                        
                                        }
                                    
                                }
                            
                            }
                        
                        }
                    break;
                    case 'acc':
                        // test if character class in arm class
                         foreach(local x in gActor.contents)
                        {
                        
                            if(gDobj == x)
                            {
                            
                                if(x.isEquipped)
                                {
                                    
                                    illogical('{that dobj/him} is already equipped.');
                                    
                                }
                            
                            }
                        
                        } 
                    break;
                    case 'itm':
                        illogical('{You/he} can\'t equip 
                       {that dobj/him}.');
                    break;
                    case 'kitm':
                         illogical('{You/he} can\'t equip 
                       {that dobj/him}.');
                    break;
                    
                }
                
            }else{
                
                 illogical('{You/he} can\'t equip 
                       {that dobj/him} without it in inventory.');
                
            }
                
            // end verify
        }

The direct object is the ‘self’ object since that’s the object verify() is called on. You don’t need gDobj. You only need that when you don’t know what the direct object is.

So all you need is:

if (isHeldBy(gActor))

Or:

if (self.isHeldBy(gActor))

if you find that more readable.

That’s a bit confusing. I’m not sure you would know the object unless it was a static defined template item using Tads 3 code. I thought if you were working in actions, within a class, or modify thing, you might never know what the object is. User could type: wield the [sword] or wield the [stick]. I thought accessing gDobj was the way to be robust, because it could be any object. Right now I’m working in modify thing.

RealNC is right, dobjFor block is a shorthand for creating just an ordinary method. If you modify Thing and add a dobjFor, then every Thing derived object will inherit your method, which means your verify will be “copied” many times for each individual object including your sword and your stick. And the one associated with the direct object player referred in a command will be triggered and executed (on that object). That’s little simplified, but should give you an idea.

The code you wrote is a method. Methods are always invoked on an object or class. That object or class is ‘self’ (which is always implied and can be omitted.)

When you type WIELD SWORD, and your sword object is a Thing, then the verify() method will be called on the sword object. That means ‘self’ is the sword object. You implemented the verify() method in Thing, yes. But your sword object inherits from Thing. That’s the whole point. Otherwise you’d need to write a verify() method for every single object in your game. But using inheritance, you only write it once in a class, and all objects that inherit from that class get it automatically.

If you instead write something like “if(gDobj && gDobj.isHeldBy(gActor))” then your verify code will simply not run when gDobj is nil. But there IS a direct object. The ‘self’ object. The object verify() is currently being called on. So you’re introducing a bug here if you use gDobj.

Only use gDobj when you actually have to. If you already know the object you’re interested it, there’s no reason to use gDobj.

Thank you Real, this is much clearer. I see. The class is Thing, self is a reference to that thing. That makes sense. I understood that anyway, not sure why I overlooked. Maybe because I was in an action and I just thought that was the way of doing it. So when don’t you know the object? I would think you could use self inside Tads 3 obect defined like this:

rubberBand: Thing 'rubber band*bands' 'rubber band' @roomName
   "A blue rubber band."
;

If you had dobjFor(Take) code on this couldn’t you also use self to reference it inside that code?

When you type TAKE RUBBER BAND, what gets called is rubberBand.verifyDobjTake(), then rubberBand.checkDobjTake() and finally rubberBand.actionDobjTake(). Not Thing.verifyDobjTake() and so on.

(Note that the dobjFor() handler is just an easier way to define the above methods. It’s not important to this discussion though.)

‘self’ is the object the method is being called on. If you call a method on some object, like “obj.method()”, then ‘self’ will be ‘obj’. When the parser calls one of the dobjFor() methods, it calls it on the direct object, not on Thing.

Cases where you don’t know what the direct object is are those where you’re not writing code inside a dobjFor() handler. For example you might be writing code in an iobjFor() handler. ‘self’ is the indirect object. If you want to access the direct object, then you’d use gDobj.