! _Shade_ ! Special source-code edition ! Copyright 2000-2002 Andrew Plotkin ! http://www.eblong.com/zarf/if.html ! This source code is provided for personal, educational use only. ! See README file for details. Class Zone with leave_fragment [; print " step out of ", (the) self; rtrue; ], enter_fragment [; print " step into ", (the) self; ], react_before [; Exit: if (player in self) { if (self provides leave_barrier && self.leave_barrier ~= NULL) { PrintOrRun(self, leave_barrier); rtrue; } move player to parent(self); if (keep_silent == 0) { print "You"; PrintOrRun(self, leave_fragment, 1); print ".^"; } rtrue; } ], before [; Enter: if (player in self) return L__M(##Enter, 1, self); MoveToZone(self, 1); rtrue; Receive: if (self has supporter) rfalse; if (player notin self) MoveToZone(self); <>; ], sand_obj 0, has scenery enterable transparent; [ FindZone obj; obj = parent(obj); while (obj) { if (obj ofclass Zone || obj == Apartment) return obj; obj = parent(obj); } return 0; ]; [ FindFloorZone obj res; res = FindZone(obj); if (res && res has supporter) res = parent(res); return res; ]; [ MoveToZone zo skipfinal anc ix jx count altform; count = 0; altform = multiflag; if (skipfinal) altform = false; anc = CommonAncestor(zo, player); if (anc == 0) "You cannot find your way."; ix = parent(player); while (ix ~= anc) { if (ix provides leave_barrier && ix.leave_barrier ~= NULL) { if (count > 0) { if (~~altform) print ".^^"; else print ".) "; } PrintOrRun(ix, leave_barrier); rtrue; } if (count == 0) { if (altform) print "("; print "You"; } else { print ", and"; } PrintOrRun(ix, leave_fragment, 1); count++; ix = parent(ix); if (ix == 0) "[BUG: Zoning: ix == 0]"; } while (ix ~= zo) { jx = zo; while (jx notin ix) { jx = parent(jx); if (jx == 0) "[BUG: Zoning: jx == 0]"; } ix = jx; if (count == 0) { if (altform) print "("; print "You"; } else { print ", and"; } PrintOrRun(ix, enter_fragment, 1); count++; } if (count > 0) { if (~~altform) { print ".^"; if (~~skipfinal) print "^"; } else { print ".)"; if (~~skipfinal) print " "; } } if (player notin zo) move player to zo; rfalse; ]; Constant OIU = ObjectIsUntouchable; [ ObjectIsUntouchable item flag1 flag2 zo inokay ix; inokay = FALSE; if (item ofclass Zone) { zo = parent(item); inokay = TRUE; } else { zo = parent(item); while (~~(zo == 0 || zo ofclass Zone || zo == Apartment)) { zo = parent(zo); } } if (zo) { ! print "[", (name) item, ": ", (name) zo, " zone.]^"; if (inokay && IndirectlyContains(item, player)) { zo = item; } ix = MoveToZone(zo); if (ix) return ix; } return Orig_OIU(item, flag1, flag2); ]; [ Orig_OIU item flag1 flag2 ancestor i; ! Determine if there's any barrier preventing the player from moving ! things to "item". Return false if no barrier; otherwise print a ! suitable message and return true. ! If flag1 is set, do not print any message. ! If flag2 is set, also apply Take/Remove restrictions. ! If the item has been added to scope by something, it's first necessary ! for that something to be touchable. i = ObjectScopedBySomething(item); if (i ~= 0) { if (ObjectIsUntouchable(i)) return; ! An item immediately added to scope } ancestor = CommonAncestor(player, item); ! First, a barrier between the player and the ancestor. The player ! can only be in a sequence of enterable objects, and only closed ! containers form a barrier. if (player ~= ancestor) { i = parent(player); while (i~=ancestor) { if (i has container && i hasnt open) { if (flag1) rtrue; return L__M(##Take,9,i); } i = parent(i); } } ! Second, a barrier between the item and the ancestor. The item can ! be carried by someone, part of a piece of machinery, in or on top ! of something and so on. if (item ~= ancestor) { i = parent(item); while (i~=ancestor) { if (flag2 && i hasnt container && i hasnt supporter) { if (i has animate) { if (flag1) rtrue; return L__M(##Take,6,i); } if (i has transparent) { if (flag1) rtrue; return L__M(##Take,7,i); } if (flag1) rtrue; return L__M(##Take,8,item); } if (i has container && i hasnt open) { if (flag1) rtrue; return L__M(##Take,9,i); } i = parent(i); } } rfalse; ]; [ RescueContents loc dest ix ix2; if (dest == 0) dest = Apartment; if (loc == 0 || loc == dest) print_ret "[BUG] RescueContents()"; ix = child(loc); while (ix) { ix2 = sibling(ix); if (ix has rescuable) { move ix to dest; } else { if (child(ix)) RescueContents(ix, dest); } ix = ix2; } ];