by Roody_Yogurt » Tue Jul 02, 2024 1:35 pm
Well, like I said in another thread, I've been digging through old problems just to see if I can shed new light on them. This identical class problem has been on my mind for years. Recently, I fixed a problem in the engine that occasionally provided a wrong object to ParseError, and I thought there was a small chance that issue had affected this problem, causing the point where the command seems to get redirected for an explicable reason.
As a refresher, the problem was this. I had coded a situation in which there were multiple identical dirty dishes. As the player washes each dish, it gets removed from the dirty dishes and added to the identical dishes group. At some point, >WASH DISH would result in "You can't see that.", instead of washing the final dirty dish.
Anyhow, the recent heparse,c fix did not have any effect on this, so I looked at the whole problem again. I noticed that if I washed all of the dirty dishes consecutively, they were all washed properly. If I >LOOKed in between steps, the problem came up.
I imagine that I first encountered this problem before I was comfortable with the debugger and before I had even learned the usefulness of the Hugofix commands. Running the game with Hugofix's Parser Monitor on showed that the code was successfully getting all the way to the Perform stage and it was choking from there. Using the debugger, I saw that the important code was in the before property for the plural class. It was checking to make sure the object had the workflag attribute, and it did not.
This explained why >LOOKing was changing the behavior, as DescribeRoom applies and clears the "already_listed" attribute to objects as it goes through the room, and already_listed is an alias of workflag.
I then searched through the library source to see where workflag was set in the processing of plurals. I eventually found the culprit in this code:
Code: Select all
for (i=1; i<=pobj.#plural_of; i++)
{
k = pobj.plural_of #i
! explicitly notheld object
if pluralobj_heldmode = -1 and k is not workflag
{
if FindObject(k, loc) and k not in actor
{
n = k
k is workflag
j++
}
}
elseif pluralobj_heldmode ~= -1
k is not workflag
! explicitly held object
if pluralobj_heldmode = 1
{
if k in actor
{
n = k
k is workflag
j++
}
}
! or neither
elseif pluralobj_heldmode = 0
{
if FindObject(k, loc)
{
n = k
k is workflag
j++
}
}
if n and plural_type = single_noun: break
if j and j = pobj_number: break
}
The problem was that in code like mine, where a plural class object has values removed throughout the course of the game (as dirty dishes become clean), some of the elements in dirtydishes.plural_of are going to be 0. So this code then proceeds to execute FindObject(0,location) which returns true since 0 (nothing) is the parent of the location. So then the code above says, ok, we found an object that works and proceeds, setting 0 as workflag and breaking out of the loop before any of the actual plural objects can be workflagged.
So, putting most of that code in an "if k" conditional fixed the problem.
The further a Hugo author gets into Hugo, the debugger (and Hugofix) just gets more and more crucial. Anyhow, the plural class system does so much additional parsing on top of a normal command that there may be more bugs to discover, but we'll take those as we find them.
Well, like I said in another thread, I've been digging through old problems just to see if I can shed new light on them. This identical class problem has been on my mind for years. Recently, I fixed a problem in the engine that occasionally provided a wrong object to ParseError, and I thought there was a small chance that issue had affected this problem, causing the point where the command seems to get redirected for an explicable reason.
As a refresher, the problem was this. I had coded a situation in which there were multiple identical dirty dishes. As the player washes each dish, it gets removed from the dirty dishes and added to the identical dishes group. At some point, >WASH DISH would result in "You can't see that.", instead of washing the final dirty dish.
Anyhow, the recent heparse,c fix did not have any effect on this, so I looked at the whole problem again. I noticed that if I washed all of the dirty dishes consecutively, they were all washed properly. If I >LOOKed in between steps, the problem came up.
I imagine that I first encountered this problem before I was comfortable with the debugger and before I had even learned the usefulness of the Hugofix commands. Running the game with Hugofix's Parser Monitor on showed that the code was successfully getting all the way to the Perform stage and it was choking from there. Using the debugger, I saw that the important code was in the before property for the plural class. It was checking to make sure the object had the workflag attribute, and it did not.
This explained why >LOOKing was changing the behavior, as DescribeRoom applies and clears the "already_listed" attribute to objects as it goes through the room, and already_listed is an alias of workflag.
I then searched through the library source to see where workflag was set in the processing of plurals. I eventually found the culprit in this code:
[code]
for (i=1; i<=pobj.#plural_of; i++)
{
k = pobj.plural_of #i
! explicitly notheld object
if pluralobj_heldmode = -1 and k is not workflag
{
if FindObject(k, loc) and k not in actor
{
n = k
k is workflag
j++
}
}
elseif pluralobj_heldmode ~= -1
k is not workflag
! explicitly held object
if pluralobj_heldmode = 1
{
if k in actor
{
n = k
k is workflag
j++
}
}
! or neither
elseif pluralobj_heldmode = 0
{
if FindObject(k, loc)
{
n = k
k is workflag
j++
}
}
if n and plural_type = single_noun: break
if j and j = pobj_number: break
}
[/code]
The problem was that in code like mine, where a plural class object has values removed throughout the course of the game (as dirty dishes become clean), some of the elements in dirtydishes.plural_of are going to be 0. So this code then proceeds to execute FindObject(0,location) which returns true since 0 (nothing) is the parent of the location. So then the code above says, ok, we found an object that works and proceeds, setting 0 as workflag and breaking out of the loop before any of the actual plural objects can be workflagged.
So, putting most of that code in an "if k" conditional fixed the problem.
The further a Hugo author gets into Hugo, the debugger (and Hugofix) just gets more and more crucial. Anyhow, the plural class system does so much additional parsing on top of a normal command that there may be more bugs to discover, but we'll take those as we find them.