Here we show a SimAntics BHAV code snippet that will find the closest sink. It loops round looking for objects of a certain type and calculating the distance between that object and the current Sim. It tests the distance of each object with the previous lowest distance and if closer saves the new distance and the new object ID. Once all objects of the type have been cycled round, we drop out of the loop and make use of the nearest object that we have found. This example will then push an interaction onto the current Sim to use the nearest sink to get a glass of water
This code snippet illustrates several primitives. Use these links to see full details about how to use these primitives in order to recreate the BHAV code below.
- Expression (0x0002)
- Set to Next (0x001F) obj with category == temp 0 varient
- Distance (0x000B)
- Push Interaction (0x000D)
The BHAV code
Firstly we start by zeroing out the Stack Object so that our loop through all the objects starts from the beginning.
0x0000: Expression (Stack Object ID := Literal 0x0000), True Target: 0x0001, False Target: Error
Then we set up our Local variables to hold the closest distance so far and the object ID of the closest object of the type we are after that we have found. We set the distance to 9999 (0x270F when displayed in hex) so the first object we find is bound to be closer than that.
0x0001: Expression (Local 0x0003 := Literal 0x270F), True Target: 0x0002, False Target: Error 0x0002: Expression (Local 0x0004 := Literal 0x0000), True Target: 0x0003, False Target: Error
Now we begin our loop round all the objects of a certain type. We are going to look for sinks. We set the value for sink types in Temp variable zero as that is what the next instruction expects. We use the Global constant for this as SimPE helpfully shows us the text assigned to the constant which helps us to know we have found the correct value.
0x0003: Expression (Temp 0x0000 := Const 0x0106:0x1C), True Target: 0x0004, False Target: Error 0x0004: Set to Next (Stack Object ID, obj with category == temp 0), True Target: 0x0005, False Target: 0x0009
If we find one, that is our Set to Next instruction returned True, we will calculate the distance between our Sim and this sink.
0x0005: Distance (Temp 0x0000 := My object id .. Stack Object), True Target: 0x0006, False Target: Error
Then we will check if it is closer than the closest one we previously found, which for the first sink found by the loop it will be. If it isn't closer then we loop back up to look for the next sink. We loop back to the instruction that sets the type into Temp 0x0000 since we used Temp 0x0000 for something else since we put that value into it, so we need to set it again.
0x0006: Expression (Temp 0x0000 < Local 0x0003), True Target: 0x0007, False Target: 0x0003
If it is closer, we save the new closest distance so far into one Local variable, and the object ID of the object that is this closest one, into another Local variable. Then we loop back to the run the loop again to see if there are any more sinks that might be closer. Note that we always loop back to the instruction that sets the value in Temp 0x0000. In many cases it might be unnecessary, since Temp 0x0000 hasn't changed, but if you call out to any function in the loop, that function may set Temp 0x0000 to something else and then your loop will be looking for a different category next time around. Certainly if you use Temp 0x0000 in your loop (as we do this time) it is essential.
0x0007: Expression (Local 0x0003 := Temp 0x0000), True Target: 0x0008, False Target: Error 0x0008: Expression (Local 0x0004 := Stack Object ID), True Target: 0x0003, False Target: Error
After the loop
Once we have exhausted all the sinks, the Set to Next instruction will return false and will jump to the instruction which is going to now use this discovered closest sink to get a glass of water. First we test whether we found any sink at all, and only if we did do we then push an interaction from that sink TTAB onto the Sim. Push Interaction always pushes onto the Stack Object so we must first set our current Sim into that variable
0x0009: Expression (Local 0x0004 > Literal 0x0000), True Target: 0x000A, False Target: True 0x000A: Expression (Stack Object ID := My object id), True Target: 0x000B, False Target: Error 0x000B: Push Interaction (Local 0x0004, Literal 0x0001, inherited priority), True Target: True, False Target: Error