TADS Programming - Sacks For ease of publication the REM markings have been removed. However I think it's clear what is code and what is a REM because I've left in the /* and */ before and after the REMs start ... Sue /* SackItem.t version 1.0 by Kevin Forchione ( Lysseus@msn.com ) Copyright (c) 1999. All Rights Reserved. You may modify and use this file in any way you want, provided that if you redistribute modified copies of this file in source form, the copies must include the original copyright notice (including this paragraph), and must be clearly marked as modified from the original version. This file defines the sackItem class and modified class thing that allows for the implementation of a 'rucksack', into which the game automatically tidies away things for the player. The sackItem class will automatically move items from the player's possession to the designated sackItem once the player attempts to take more than the maximum bulk allocated for them. This file should be #include'd after ADV.T and STD.T at the start of your game source source file. REQUIRES HTML TADS 2.2.6 OR LATER Revision History 99-03-10 programming begun. */ /* We modify only the totbulk logic of thing (the idea being that a player can only carry so much weight regardless of whether they have a sack or not. */ modify thing doTake(actor) = { local totbulk, totweight; totbulk := addbulk(actor.contents) + self.bulk; totweight := addweight(actor.contents); if (not actor.isCarrying(self)) totweight := totweight + self.weight + addweight(self.contents); if (totweight > actor.maxweight) "%Your% load is too heavy. "; else if (totbulk > actor.maxbulk) { if ( self.moveToSackItem( actor ) ) { self.moveInto( actor ); "Taken. "; } else "%You've% already got %your% hands full. "; } else { self.moveInto(actor); "Taken. "; } } /* This is the heart of the sackItem logic. The logic does not check for multiple sackItems, it takes the first one it finds Also it does not attempt to optimise the placement of items in the sackItem, except that items that are lit or that are being worn are not chosen. */ moveToSackItem( actor ) = { local c, n := [], o, s, totbulk; /* determine if the actor is carrying a sackItem */ c := actor.contents; o := car( c ); while( o ) { if ( isclass( o, sackItem ) ) { break; } c := cdr( c ); o := car( c ); }; s := o; // sackItem value if ( s = nil ) return nil; c := actor.contents - [ s ]; // exclude the sackItem /* Select items that aren't being worn or that aren't lit as candidates for the sackItem. */ o := car( c ); while( o ) { if ( not o.isworn and not o.islit ) { n := n + [ o ]; } c := cdr( c ); o := car( c ); } /* Determine if an object will fit in the sack and move it if it does. */ o := car( n ); while( o ) { totbulk := addbulk( s.contents ) + o.bulk; if ( totbulk <= s.maxbulk ) { o.moveInto( s ); "(putting <> into <> to make room)\n"; return true; }; n := cdr( n ); o := car( n ); } return nil; } ; /* sackItem: openable, clothingItem This class allows an object to act like a 'rucksack', into which the game automatically tidies away things for the player. */ class sackItem: openable, clothingItem maxbulk = 20 ; - o -