The former. When applied to objects, the == operator does not check for equality, but for identity. Even if two objects, obj1 and obj2, would otherwise be equal (like when you have two copies of the same object, or two vectors with the same contents), “obj1 == obj2” will evaluate to nil, because they are not the same object. This is because objects in TADS use reference semantics.
Note that this only applies to objects. Other types use value semantics. Two different variables for example will be equal if they contain the same number. Also note that lists are value types, not objects.
Thanks, Real. How do I check if two objects are the same? I need to test if my creature target on Monster class target member = target found in a loop of room contents so I can update the actual obj health after damage.
Sorry, I guess the message was a little confusing:
“When applied to objects, the == operator does not check for equality, but for identity.”
That’s what I want to do.
“Even if two objects, obj1 and obj2, would otherwise be equal (like when you have two copies of the same object, or two vectors with the same contents), “obj1 == obj2” will evaluate to nil, because they are not the same object.”
That’s what’s making it confusing because two copies of the same object is exactly what I have. I have a monster class with a member called target. I set that target by looping over room contents and choosing a random Actor. I’ve applied damage in my attack function but now I have to update the actual room object from my member target.
They are the same object, but they don’t have all the same values anymore.
== will work, or will that give ‘nil’ in return.
That leads me to another question.
If I do this:
local room = self.getOutermostRoom();
And update room.contents will that affect the actual contents in the room or just that copy. Kind of a dumb question at this point, but getting worried now, lol.
No, they have the same members, but different values. I’ve updated the target in the target member on the class. It shouldn’t be the same as the object in the room, unless there is a pointer.
Yeah, that’s what’s messing us up. I don’t know if it’s making a copy by reference or a copy by val.
local room = self.getOutermostRoom();
local roomObjects = room.contents;
local targetList = [];
I then looped over the roomObjects list and if it was kindOf Actor and !Monster it is a Actor that gets added. If it was kindOf Monster and Actor it was a monster that got added. I select a target from the target list randomly depending on if the monster can target just characters or other monsters too. That gets added to target on my Monster class.
Now when I update my target in my attack function I assume I’m just updating a shallow copy and now need to set the hp on that target to the hp on the room object again. I don’t want to just be updating shallow copies in my class.
attack(attacks)
{
// attack
local normalAttacks = [];
foreach(local x in attacks)
{
if(!x.isSpecial)
{
normalAttacks = normalAttacks.append(x);
}
}
if(normalAttacks.length() >= 1)
{
// making attack
local ind = self.roll(1, normalAttacks.length());
local attack = normalAttacks[ind];
local dmgRoll = self.roll(attack.lowerDmg, attack.upperDmg);
local damage = (dmgRoll) - (self.target.armourClass + self.target.defBonus);
damage = max(0, damage);
self.target.hp = self.target.hp - damage;
self.target.hp = max(0, self.target.hp);
// loop to find actual target in room and apply damage
// output damage desc
if(!attack.hasLongDesc)
{
"<<self.name>> <<attack.verb>> <<self.target.name>> for <<damage>>dmg.";
}else{
// use attack long description
local indCount = attack.longDescriptions.length();
local descInd = self.roll(1, indCount);
"<<attack.longDescriptions[descInd]>>";
// end use attack long description
}
// show attack output
// end making attack
}
// end attack
}
When I edit roomContents am I updating actual room objects, or a shallow copy? If I would be updating the actual value of the room object, wouldn’t it be the same for my target on Monster class?
“even if several variables refer to a list value, each variable effectively has its own private copy of the list, so changes made to one variable’s list won’t affect any others.”
However, it’s not advisable to modify the ‘contents’ property. It should be treated as an internal property. When you want to remove an object from a location, use moveInto(). There are a lot of things that need to happen when moving an object from one location to another. It’s not just a matter of putting it or removing it from the ‘contents’ property.
You don’t. You use moveInto() instead of trying to modify the ‘contents’ property.
Now I’m horribly confused. What object? We were talking about the ‘contents’ property, which is a list. If you use the = operator with it, you take a shallow copy of the list. All the contents of that list are the same objects as those in the original list, they are not copies.
I don’t need moveInto, because I’m not adding a new object to the room. I’m trying to update an object that already exists in the room.
I want to transfer my target.hp onto the actual object. I’ll simplify the code.
class Monster
target = nil
set_target()
{
local room = self.getOutermostRoom();
local roomObjects = room.contents;
foreach(local x in roomObjects)
{
self.target = random index from roomObjects if type Actor
}
}
attack()
{
self.target.hp - 10;
}
updateTarget()
{
// make room object that is the target have hp = self.target.hp
}
;
I’m stuck in the updateTarget part of my logic. If I’m working with a copy, how do I do the update part?
‘self.target’ IS the object you want. As said before, objects in TADS are not copied. They use reference semantics:
local obj1 = someObj;
local obj2 = obj1;
‘someObj’, ‘obj1’ and ‘obj2’ are all the same object. It doesn’t matter if you write ‘obj1.hp = 10’ or ‘someObj.hp = 10’. It will modify the ‘hp’ property of the same object.
Sorry, I could have swore you said value semantics, lol. Sorry about that. So every time I do this:
local room = self.getOutermostRoom();
local roomObjects = room.contents;
Tads 3 has internally used pointers to give me actual memory access to the original objects for each object in the list? Or in the least, effectively gave me the equivalent. Even if I transfer an object from the list to a member, like my target member?
I hate to ask a simple bug question but my switch case isn’t working in dobjFor(Wield). The error complains about unbalanced braces. I’ve taken all the code out and still has the same complaint.
Edit: Nevermind, sorry. My error was spelling switch as stwich.
I’m making a wield verb but it’s giving me problems with gDobj being a nil object reference. It’s right at the start. There’s more code, but it’s all inside the if statement.
The global variables (gDobj, gIobj, …) are not known till the very end the the verify process. The global variables are not normally used in verify for that reason. If you change your code to what I have below the nil object reference should go away.