Replace CheckReach
What it fixes
The original CheckReach can be fooled by some instances of components. This version checks than an object is not a part of something within reach before returning false.
The code
replace CheckReach(obj)
{
local i,p
if not obj or obj = parent(player)
return true
#ifclear NO_VERBS
if (verbroutine ~= &DoLook, &DoLookIn) and parent(object) and
parent(object) ~= player and
parent(object) is transparent and parent(object) is not open and
parent(object) is not living
{
VMessage(&DoGet, 5) ! "X is closed."
return false
}
#endif
if not parent(player).reach or
Contains(parent(player), obj)
return true
p = obj.part_of
while p
{
if Contains(parent(player), p)
return true
p = p.part_of
}
#ifclear NO_VERBS
if parent(obj) is living
{
if verbroutine ~= &DoGet, &DoLook
! "Except that X has it..."
Message(&CheckReach, 1, obj)
elseif verbroutine = &DoGet and parent(obj) is unfriendly
! "Except that X doesn't want to give it to you..."
Message(&CheckReach, 2, obj)
}
#endif
for (i=1; i<=parent(player).#reach; i++)
{
if Contains(parent(player).reach #i, obj) or ! is the object inside a reach object
obj = parent(player).reach #i ! is the object a reach object
{
return true
}
}
p = obj.part_of
while p
{
for (i=1; i<=parent(player).#reach; i++)
{
if Contains(parent(player).reach #i, p) or ! is the object part of an object inside the reach object
p = parent(player).reach #i ! is the object part of a reach object
{
return true
}
}
p = p.part_of
}
#ifset USE_ATTACHABLES
if parent(player).type = attachable
{
if InList(parent(player), attached_to, obj)
return true
}
if obj.type = attachable
{
if InList(obj, attached_to, parent(player))
return true
}
#endif
! "You can't reach it..."
Message(&CheckReach, 3, obj)
}