home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #7
/
amigamamagazinepolishissue1998.iso
/
rozrywka
/
rpg
/
amigamud
/
src
/
basics
/
util2.m
< prev
next >
Wrap
Text File
|
1997-08-07
|
30KB
|
1,178 lines
/*
* Amiga MUD
*
* Copyright (c) 1997 by Chris Gray
*/
/*
* util2.m - more utility stuff. These are a bunch of small modules.
*/
private tp_util2 CreateTable()$
use tp_util2
/***************************************************************************/
/*
* AddLight - introduce a source of light to the current room.
*/
define t_util proc public AddLight()void:
if not CanSee(Here(), Me()) then
if DoRoomLightChecks(Here()) ~= fail then
ignore ShowRoomToMe(false);
ForEachAgent(Here(), ShowRoomToAgent);
fi;
fi;
corp;
/*
* ActiveLightObject - an object is made to now emit light.
*/
define t_util proc public ActiveLightObject()status:
thing it;
string name;
it := It();
name := FormatName(it@p_oName);
if it@p_oLight then
Print("The " + name + " is already lit.\n");
fail
else
Print("You light the " + name + ".\n");
OPrint(Capitalize(CharacterNameG(Me())) +
AAn(" lights", name) + ".\n");
AddLight();
it@p_oLight := true;
/* want these to be succeed to allow proper use with VerbHere, etc. */
succeed
fi
corp;
/*
* RemoveLight - remove a source of light from the current room.
*/
define t_util proc public RemoveLight()void:
if not CanSee(Here(), Me()) then
UnShowRoomFromMe();
ForEachAgent(Here(), UnShowRoomFromAgent);
fi;
corp;
/*
* ActiveUnLightObject - an object is made to no longer emit light.
*/
define t_util proc public ActiveUnLightObject()status:
thing it;
string name;
it := It();
name := FormatName(it@p_oName);
if not it@p_oLight then
Print("The " + name + " is not lit.\n");
fail
else
Print("You extinguish the " + name + ".\n");
it@p_oLight := false;
RemoveLight();
succeed
fi
corp;
/*
* PassiveUnLightObject - an object is going out, independent of any player.
*/
define t_util proc public PassiveUnLightObject(thing object)void:
thing who, where;
character ch;
object@p_oLight := false;
who := object@p_oCarryer;
where := object@p_oWhere;
if who ~= nil then
SPrint(who, "Your " + FormatName(object@p_oName) + " has gone out.\n");
ch := Character(who@p_pName);
if ch ~= nil and CharacterThing(ch) = who then
where := CharacterLocation(ch);
if not LightAt(where) then
ForEachAgent(where, UnShowRoomFromAgent);
fi;
fi;
elif where ~= nil and not LightAt(where) then
ForEachAgent(where, UnShowRoomFromAgent);
fi;
corp;
/***************************************************************************/
/*
* GetDocument - get a long document - e.g. description, letter, etc.
* Callable by player or machine - will do nothing for a machine.
* There are some things to watch out for here. We want these routines
* to be 'utility' so that they can be used properly by the build code.
*/
define tp_util2 p_pOldDoc CreateStringProp()$
define tp_util2 p_pEndAction CreateActionProp()$
define tp_util2 p_pRawDocument CreateBoolProp()$
define tp_util2 p_pTempString CreateStringProp()$
define tp_util2 p_pSavePrompt CreateStringProp()$
define tp_util2 p_pSaveAction CreateActionProp()$
/* 'docReset' is replaced later, when its references can be satisfied */
define tp_util2 proc docReset()void: corp;
/* Append the given string to the document being built up. This was
originally set up for the line-by-line mode, but is also used for
its handling of the end-of-input condition (s = ".") */
define tp_util2 proc utility appendToDocument(string line)void:
action endAction;
thing me, letter;
string s;
int len;
me := Me();
s := me@p_pTempString;
len := Length(s);
if line = "." or line = "$" then
if len >= 4000 then
Print("*** Warning - input may have been truncated. ***\n");
fi;
endAction := me@p_pEndAction;
docReset();
/* call this so that, e.g. a normal person using the build code can
modify his own objects that are ts_readonly */
call(endAction, void)(s);
else
if len >= 4000 then
Print("*** Warning - input has been truncated. ***\n");
else
if me@p_pRawDocument then
me@p_pTempString := s + line + "\n";
else
if line ~= "" then
if s ~= "" then
s := s + " ";
fi;
me@p_pTempString := s + line;
fi;
fi;
fi;
fi;
corp;
/* Called when the player exits MUD while still entering a document. */
define tp_util2 proc utility docIdleAction()void:
Me()@p_pTempString := Me()@p_pOldDoc;
appendToDocument(".");
corp;
/* Called by 'activeAction' if the database was saved while the player
was entering a document, and the server was later restarted from that
saved database. */
define tp_util2 proc docActiveAction()void:
Print("\n* You were editing/entering something when the last backup "
"was made. That text change has been lost. *\n\n");
docIdleAction();
corp;
/* We can now define the full body of this. Basically, just clean up after
doing a GetDocument. */
replace docReset()void:
thing me;
me := Me();
DelElement(me@p_pEnterActions, docActiveAction);
DelElement(me@p_pExitActions, docIdleAction);
if me@p_pSaveAction ~= nil then
/* not setup if using 'EditString' */
ignore SetCharacterInputAction(me@p_pSaveAction);
me -- p_pSaveAction;
ignore SetPrompt(me@p_pSavePrompt);
me -- p_pSavePrompt;
fi;
me -- p_pTempString;
me -- p_pOldDoc;
me -- p_pEndAction;
me -- p_pRawDocument;
corp;
/* Called when the user finished editting the document, as part of
'EditString'. */
define tp_util2 proc utility docEndAction(string s; bool ok)void:
thing me;
me := Me();
if ok then
me@p_pTempString := s;
else
me@p_pTempString := me@p_pOldDoc;
fi;
appendToDocument(".");
corp;
/* Set things up so that user input will be accumulated into a document
of some kind, which will then be passed to 'endAction'. Also handle
cases of input not completed when player exits, or when a backup is
made and later used. */
define t_util proc utility GetDocument(string prompt, intro, oldDoc;
action endAction; bool isRaw)bool:
thing me;
action oldAction;
me := Me();
if CanEdit() then
if Editing() then
Print("You are alreadying editing something!\n");
false
else
me@p_pTempString := "";
me@p_pEndAction := endAction;
me@p_pRawDocument := isRaw;
me@p_pOldDoc := oldDoc;
AddHead(me@p_pEnterActions, docActiveAction);
AddHead(me@p_pExitActions, docIdleAction);
EditString(oldDoc, docEndAction,
if isRaw then EDIT_RAW else EDIT_COOKED fi,
intro);
true
fi
else
oldAction := SetCharacterInputAction(appendToDocument);
if oldAction = nil then
/* must have been a machine! */
OPrint(Capitalize(CharacterNameS(me)) + " is confused.\n");
false
else
me@p_pTempString := "";
me@p_pEndAction := endAction;
me@p_pRawDocument := isRaw;
me@p_pOldDoc := oldDoc;
AddHead(me@p_pEnterActions, docActiveAction);
AddHead(me@p_pExitActions, docIdleAction);
me@p_pSavePrompt := SetPrompt("* " + prompt);
me@p_pSaveAction := oldAction;
Print(intro +
". End with a line containing only a single period.\n");
true
fi
fi
corp;
/*
* GetCheckedDescription - variant which lets a routine of the callers handle
* each of the input lines. Note that since we need line-by-line
* processing, there is no 'EditString' variation here.
*/
define t_util proc utility GetCheckedEnd()void: corp; /* replaced later */
define tp_util2 proc checkedActiveAction()void:
Print("\n* You were entering something when the last backup "
"was made. Those changes have been lost. *\n\n");
GetCheckedEnd();
corp;
/*
* GetCheckedEnd - this can be called by other code (e.g. the handler for
* this checked description) to terminate this input mode, e.g.
* because of erroneous user input.
*/
replace GetCheckedEnd()void:
thing me;
me := Me();
ignore SetCharacterInputAction(me@p_pSaveAction);
me -- p_pSaveAction;
ignore SetPrompt(me@p_pSavePrompt);
me -- p_pSavePrompt;
DelElement(me@p_pEnterActions, checkedActiveAction);
DelElement(me@p_pExitActions, GetCheckedEnd);
corp;
define t_util proc utility GetCheckedDescription(string prompt;
action lineHandler)bool:
thing me;
action oldAction;
me := Me();
oldAction := SetCharacterInputAction(lineHandler);
if oldAction = nil then
/* must have been a machine! */
OPrint(Capitalize(CharacterNameS(me)) + " is confused.\n");
false
else
me@p_pSaveAction := oldAction;
me@p_pSavePrompt := SetPrompt("* " + prompt);
AddHead(me@p_pEnterActions, checkedActiveAction);
AddHead(me@p_pExitActions, GetCheckedEnd);
true
fi
corp;
/***************************************************************************/
/*
* Paginate - paginate a string within the output screen size.
*/
define tp_util2 p_pPaginateSetup CreateBoolProp()$
define tp_util2 p_pPaginateString CreateStringProp()$
define tp_util2 p_pPaginateLen CreateIntProp()$
define tp_util2 p_pPaginatePrompt CreateStringProp()$
define tp_util2 p_pPaginateHandler CreateActionProp()$
define tp_util2 proc paginateReset()void:
thing me;
me := Me();
me -- p_pPaginateString;
me -- p_pPaginateLen;
if me@p_pPaginateSetup then
me -- p_pPaginateSetup;
DelElement(me@p_pEnterActions, paginateReset);
DelElement(me@p_pExitActions, paginateReset);
ignore SetPrompt(me@p_pPaginatePrompt);
me -- p_pPaginatePrompt;
ignore SetCharacterInputAction(me@p_pPaginateHandler);
me -- p_pPaginateHandler;
fi;
corp;
define tp_util2 proc paginateParse(string line)void: corp;
define tp_util2 proc paginateShowPage()void:
thing me;
string s;
int len, i, line, height, width;
me := Me();
s := me@p_pPaginateString;
len := me@p_pPaginateLen;
height := TextHeight(0) - 1;
width := TextWidth(0);
line := 1;
while len > 0 and line <= height do
i := Index(s, "\n");
if i = -1 then
Print(s);
Print("\n");
len := 0;
else
Print(SubString(s, 0, i + 1));
s := SubString(s, i + 1, len - i - 1);
len := len - i - 1;
if i <= width then
line := line + 1;
else
line := line + (i + width - 4) / (width - 9);
fi;
fi;
od;
if len = 0 then
paginateReset();
else
me@p_pPaginateString := s;
me@p_pPaginateLen := len;
if not me@p_pPaginateSetup then
me@p_pPaginateSetup := true;
me@p_pPaginatePrompt := SetPrompt("[M O R E] ");
me@p_pPaginateHandler := SetCharacterInputAction(paginateParse);
AddHead(me@p_pEnterActions, paginateReset);
AddHead(me@p_pExitActions, paginateReset);
fi;
fi;
corp;
replace paginateParse(string line)void:
if line = "" then
paginateShowPage();
elif line == "q" then
paginateReset();
else
Print("Options are:\n q - quit\n empty line - next page\n");
fi;
corp;
define t_util proc Paginate(string s)void:
thing me;
int len;
len := Length(s);
if SubString(s, len - 1, 1) ~= "\n" then
s := s + "\n";
fi;
me := Me();
if GType(nil) == "amiga" then
/* using full MUD client - no reason to paginate */
Print(s);
elif Character(me@p_pName) = nil then
OPrint(Capitalize(CharacterNameS(me)) + " is confused.\n");
else
me@p_pPaginateString := s;
me@p_pPaginateLen := len;
paginateShowPage();
fi;
corp;
/***************************************************************************/
/* code, etc. to assist/handle buying things in stores */
/* pre-create the lost and found room, so that we can set the 'home' of
things that people buy */
define tp_misc r_lostAndFound CreateThing(r_indoors)$
SetupRoom(r_lostAndFound, "in the lost and found room",
"Things lost often end up here.")$
/*
* AddForSale - add an item for sale at the given location.
* Note: we WANT this one 'utility' so that it does not execute with
* SysAdmin privileges.
*/
define t_util proc utility public AddForSale(thing room; string name, desc;
int price; action doBuy)thing:
thing model;
list thing lt;
model := CreateThing(nil);
/* other players need to read it when shopping or buying */
SetThingStatus(model, ts_readonly);
model@p_oName := name;
if desc ~= "" then
model@p_oDesc := desc;
fi;
model@p_oPrice := price;
if doBuy ~= nil then
model@p_oBuyChecker := doBuy;
fi;
model@p_oHome := r_lostAndFound;
lt := room@p_rBuyList;
if lt = nil then
lt := CreateThingList();
room@p_rBuyList := lt;
fi;
if FindElement(lt, model) = -1 then
AddTail(lt, model);
fi;
model
corp;
/*
* AddObjectForSale - make an already defined object be for sale.
*/
define t_util proc utility public AddObjectForSale(thing room, model;
int price; action doBuy)void:
list thing lt;
model@p_oPrice := price;
if doBuy ~= nil then
model@p_oBuyChecker := doBuy;
fi;
lt := room@p_rBuyList;
if lt = nil then
lt := CreateThingList();
room@p_rBuyList := lt;
fi;
if FindElement(lt, model) = -1 then
AddTail(lt, model);
fi;
corp;
/*
* SubObjectForSale - make an object no longer for sale.
*/
define t_util proc utility public SubObjectForSale(thing room, model)bool:
list thing lt;
lt := room@p_rBuyList;
if lt ~= nil then
if FindElement(lt, model) ~= -1 then
DelElement(lt, model);
model -- p_oPrice;
model -- p_oBuyChecker;
true
else
false
fi
else
false
fi
corp;
/*
* ShowForSale - show the things for sale at a player's current location.
*/
define t_util proc public ShowForSale()void:
list thing lt;
int count, n, price;
thing model;
lt := Here()@p_rBuyList;
if lt = nil then
Print("There is nothing for sale here.\n");
else
if not Me()@p_pHidden then
OPrint(Capitalize(CharacterNameG(Me())) +
" examines the merchandise.\n");
fi;
Print("For sale here:\n");
count := Count(lt);
n := 0;
while n ~= count do
model := lt[n];
Print(" " + FormatName(model@p_oName) + " - ");
price := model@p_oPrice;
if price = 0 then
Print("free");
elif price = 1 then
Print("1 bluto");
else
IPrint(price);
Print(" blutos");
fi;
Print("\n");
n := n + 1;
od;
fi;
corp;
/*
* StoreBuy - let the user buy something at a store. This is used as the
* 'buy' action at the store location.
* Note: this is NOT a utility proc, since we want the object to
* be owned by SysAdmin, and since we use OPrint.
* Note: intended only to be called by the player doing the buy.
* Looks like it would work for machines too, however.
*/
define t_util proc public StoreBuy(string what)bool:
thing here, model, me, th;
string name;
int price, money;
action buyAction;
status st;
here := Here();
if here@p_rBuyList = nil then
Print("There is nothing for sale here.\n");
false
else
name := FormatName(what);
st := FindName(here@p_rBuyList, p_oName, what);
if st = fail then
Print(AAn("You cannot buy", name) + " here.\n");
false
elif st = continue then
Print(Capitalize(name) + " is ambiguous here.\n");
false
else
model := FindResult();
me := Me();
price := model@p_oPrice;
money := me@p_pMoney;
name := FormatName(model@p_oName);
if price > money and not me@p_pPrivileged then
Print(AAn("You cannot afford", name) + ".\n");
false
else
/* Skip past one level of inheritance if that is there. This
allows using the same model, with different price, in
different stores. */
th := Parent(model);
if th ~= nil and th@p_oPrice ~= 0 then
th := CreateThing(th);
else
th := CreateThing(model);
fi;
/* We want the thing public so that anyone can do things to
it. ts_readonly would work not bad, but that prevents
a builder from modifying it. We want it owned by SysAdmin
so that all the code that is setuid SysAdmin has no
trouble with it. We have to do the SetThingStatus BEFORE
we give it away, else we will not have access to do so. */
SetThingStatus(th, ts_public);
GiveThing(th, SysAdmin);
if model@p_oContents ~= nil then
th@p_oContents := CreateThingList();
fi;
th@p_oCreator := me;
buyAction := model@p_oBuyChecker;
st := continue;
if buyAction ~= nil then
SetIt(th);
st := call(buyAction, status)();
fi;
if st = continue and not CarryItem(th) then
st := fail;
fi;
if st ~= fail and not me@p_pPrivileged then
me@p_pMoney := money - price;
fi;
if st = continue then
Print(AAn("You have just bought", name) + ".\n");
if not me@p_pHidden then
OPrint(Capitalize(CharacterNameG(me)) +
" makes a purchase.\n");
fi;
else
/* This call will destroy the object. */
ClearThing(th);
fi;
true
fi
fi
fi
corp;
/*
* MakeStore - make a room a store.
*/
define t_util proc utility public MakeStore(thing room)void:
room@p_rBuyAction := StoreBuy;
corp;
/*
* IsStore - ask if room is a store.
*/
define t_util proc utility public IsStore(thing room)bool:
room@p_rBuyAction = StoreBuy
corp;
/*
* UnmakeStore - make a room no longer a store.
*/
define t_util proc utility public UnmakeStore(thing room)void:
room -- p_rBuyList;
room -- p_rBuyAction;
corp;
/***************************************************************************/
/* Some stuff to implement banks. Note that these properties are private,
so no-one else can change bank accounts. Note also that the routines are
NOT utility routines, since we want the things created to represent the
accounts to not be owned by the player. */
define tp_util2 p_rBankAccounts CreateThingListProp()$ /* bank account list */
define tp_util2 p_oAccountValue CreateIntProp()$ /* value in account */
define tp_util2 p_oAccountOwner CreateThingProp()$ /* who owns account */
define tp_util2 proc bankDeposit()void:
list thing lt;
int money, amount, count, i;
thing me, account;
string st, name;
st := GetWord();
if st = "" then
Print("You must say how many blutos you wish to deposit.\n");
else
amount := StringToInt(st);
if amount < 0 then
Print("Invalid amount - must be a number.\n");
else
lt := Here()@p_rBankAccounts;
if lt = nil then
Print("*** no account list found ***\n");
else
me := Me();
money := me@p_pMoney;
if amount > money then
Print("You do not have that much money on you.\n");
else
count := Count(lt);
i := 0;
while
if i = count then
false
else
account := lt[i];
account@p_oAccountOwner ~= me
fi
do
i := i + 1;
od;
name := CharacterNameG(me);
if i = count then
Print("Setting up a new account for \"" + name +
"\". ");
account := CreateThing(nil);
account@p_oAccountOwner := me;
AddTail(lt, account);
i := 0;
else
i := account@p_oAccountValue;
fi;
me@p_pMoney := money - amount;
amount := amount + i;
account@p_oAccountValue := amount;
Print("Thank you for your deposit. Your account now has "
"a balance of ");
if amount = 1 then
Print("one bluto.\n");
else
IPrint(amount);
Print(" blutos.\n");
fi;
if not me@p_pHidden and CanSee(Here(), me) then
OPrint(Capitalize(name) + " makes a transaction.\n");
fi;
fi;
fi;
fi;
fi;
corp;
define tp_util2 proc bankWithdraw()void:
list thing lt;
int amount, count, i;
thing me, account;
string st;
st := GetWord();
if st = "" then
Print("You must say how many blutos you wish to withdraw.\n");
else
amount := StringToInt(st);
if amount < 0 then
Print("Invalid amount - must be a number.\n");
else
lt := Here()@p_rBankAccounts;
if lt = nil then
Print("*** no account list found ***\n");
else
me := Me();
count := Count(lt);
i := 0;
while
if i = count then
false
else
account := lt[i];
account@p_oAccountOwner ~= me
fi
do
i := i + 1;
od;
if i = count then
Print("I'm sorry, this bank has no account for \"" +
me@p_pName + "\".\n");
else
i := account@p_oAccountValue;
if amount > i then
Print("I'm sorry, you do not have that much in "
"your account.\n");
else
me@p_pMoney := me@p_pMoney + amount;
amount := i - amount;
account@p_oAccountValue := amount;
if amount = 0 then
Print("Withdrawal made. Your account is now "
"empty and has been closed.\n");
DelElement(lt, account);
else
Print("Withdrawal made. Your account now has a "
"balance of ");
if amount = 1 then
Print("one bluto.\n");
else
IPrint(amount);
Print(" blutos.\n");
fi;
fi;
fi;
if not me@p_pHidden and CanSee(Here(), me) then
OPrint(Capitalize(CharacterNameG(me)) +
" makes a transaction.\n");
fi;
fi;
fi;
fi;
fi;
corp;
define tp_util2 proc bankBalance()void:
list thing lt;
int amount, count, i;
thing me, account;
lt := Here()@p_rBankAccounts;
if lt = nil then
Print("*** no account list found ***\n");
else
me := Me();
count := Count(lt);
i := 0;
while
if i = count then
false
else
account := lt[i];
account@p_oAccountOwner ~= me
fi
do
i := i + 1;
od;
if i = count then
Print("I'm sorry, this bank has no account for \"" + me@p_pName +
"\".\n");
else
amount := account@p_oAccountValue;
Print("Your account has a balance of ");
if amount = 1 then
Print("one bluto.\n");
else
IPrint(amount);
Print(" blutos.\n");
fi;
if not me@p_pHidden and CanSee(Here(), me) then
OPrint(Capitalize(CharacterNameG(me)) +
" makes a transaction.\n");
fi;
fi;
fi;
corp;
/*
* make this one utility, so people can only do it to their own rooms.
*/
define t_util proc utility public MakeBank(thing room)void:
room@p_rBankAccounts := CreateThingList();
AddSpecialCommand(room, "deposit", bankDeposit);
AddSpecialCommand(room, "withdraw", bankWithdraw);
AddSpecialCommand(room, "balance", bankBalance);
corp;
define t_util proc utility public IsBank(thing room)bool:
room@p_rBankAccounts ~= nil
corp;
define t_util proc utility public UnmakeBank(thing room)status:
list thing accounts;
accounts := room@p_rBankAccounts;
if accounts = nil then
continue
elif Count(accounts) ~= 0 then
fail
else
room -- p_rBankAccounts;
ignore RemoveSpecialCommand(room, "deposit", bankDeposit);
ignore RemoveSpecialCommand(room, "withdraw", bankWithdraw);
ignore RemoveSpecialCommand(room, "balance", bankBalance);
succeed
fi
corp;
/***************************************************************************/
/* Some general routines for setting up verbs that do things to things.
'VerbCarry' requires that the player be carrying the object in order to
do whatever to it. 'VerbHere' allows it to be either carried or in the
room the player is in. It would also be possible to look at things that
are carried by other players/machines, but I chose not to. Note that
I check the player, then the room, then the specific object.
Return 'false' if we were not able to do the action on the requested
thing, because the thing is not available, or the action fails.
*/
/* A problem has cropped up with the drinking monsters. The code below
looks for the same properties on the player, the room and the object.
So, if you try to drink the drinking troll, it will execute the drink
action on the troll and say that you shouldn't do that. Unfortunately,
that action is also done when the troll's special action gets the troll
to 'drink water'. Proper solution is two more properties, sigh. This
has been done for the indirect case with 'actorCheck'. Thus we do not
allow the case of attaching a string to the player which is the entire
result of trying to do that action. */
define t_util proc public commonVerbTail(property string direct;
property action indirect, actorCheck; thing object;
string failHeader, verbName, name)bool:
thing me, here;
action a;
string directString;
status st;
bool doneOne;
/* Note: the status values returned by the handler routines are
interpreted as follows:
continue - nothing special - keep looking for something special
succeed - successfully handled this case
fail - this case is handled, but cease cases and parsing
The presence of a 'direct' string property is taken to be the same
as a routine which prints that string and returns 'succeed', with
the exception that something on a given object will override a
direct string on a location.
*/
me := Me();
here := Here();
doneOne := false;
if actorCheck ~= nil then
a := me@actorCheck;
if a ~= nil then
SetIt(object);
st := call(a, status)();
if st ~= continue then
doneOne := true;
fi;
fi;
fi;
if not doneOne and indirect ~= nil then
a := here@indirect;
if a ~= nil then
SetIt(object);
st := call(a, status)();
if st ~= continue then
doneOne := true;
fi;
fi;
fi;
if not doneOne and direct ~= nil then
directString := here@direct;
if directString ~= "" and
(object = nil or object@direct = "" and object@indirect = nil)
then
doneOne := true;
Print(directString + "\n");
st := continue;
fi;
fi;
if not doneOne and object ~= nil and indirect ~= nil then
a := object@indirect;
if a ~= nil then
SetIt(object);
st := call(a, status)();
if st ~= continue then
doneOne := true;
fi;
fi;
fi;
if not doneOne and object ~= nil and direct ~= nil then
directString := object@direct;
if directString ~= "" then
doneOne := true;
Print(directString + "\n");
st := continue;
fi;
fi;
if doneOne then
st ~= fail
elif object = nil then
Print("You must specify what you want to " + verbName + ".\n");
false
else
Print(failHeader + " the " + name + ".\n");
true
fi
corp;
define t_util proc public VerbCarry(string verbName; property string direct;
property action indirect, actorCheck; string failHeader, what)bool:
thing object;
string name;
status st;
bool done, ok;
list thing lt;
int i, count, oldCount;
done := false;
if what = "" then
object := nil;
elif what == "all" then
lt := Me()@p_pCarrying;
count := Count(lt);
i := 0;
ok := true;
while ok and i ~= count do
object := lt[i];
if not object@p_oInvisible then
done := true;
if commonVerbTail(direct, indirect, actorCheck,
object, failHeader, verbName, FormatName(object@p_oName))
then
oldCount := count;
count := Count(lt);
i := i - (oldCount - count) + 1;
else
ok := false;
fi;
else
i := i + 1;
fi;
od;
if not done then
done := true;
Print("You are not carrying anything obvious to " + verbName +
".\n");
ok := false;
fi;
else
name := FormatName(what);
st := FindName(Me()@p_pCarrying, p_oName, what);
if st = fail then
Print(AAn("You are not carrying", name) + ".\n");
ok := false;
done := true;
elif st = continue then
Print(Capitalize(name) + " is ambiguous here.\n");
ok := false;
done := true;
else
object := FindResult();
name := FormatName(object@p_oName);
fi;
fi;
if done then
ok
else
commonVerbTail(direct, indirect, actorCheck,
object, failHeader, verbName, name)
fi
corp;
define t_util proc public VerbHere(string verbName; property string direct;
property action indirect, actorCheck; string failHeader, what)bool:
thing here, object;
list thing lt;
int count, i, oldCount;
string ambig, name;
status st;
bool done, ok;
here := Here();
done := false;
object := nil;
if what == "all" then
lt := Me()@p_pCarrying;
count := Count(lt);
i := 0;
ok := true;
while ok and i ~= count do
object := lt[i];
if not object@p_oInvisible then
done := true;
if commonVerbTail(direct, indirect, actorCheck, object,
failHeader, verbName, FormatName(object@p_oName))
then
oldCount := count;
count := Count(lt);
i := i - (oldCount - count) + 1;
else
ok := false;
fi;
else
i := i + 1;
fi;
od;
lt := here@p_rContents;
count := Count(lt);
i := 0;
while ok and i ~= count do
object := lt[i];
if not object@p_oInvisible then
done := true;
if commonVerbTail(direct, indirect, actorCheck,
object, failHeader, verbName, FormatName(object@p_oName))
then
oldCount := count;
count := Count(lt);
i := i - (oldCount - count) + 1;
else
ok := false;
fi;
else
i := i + 1;
fi;
od;
if not done then
done := true;
Print("There is nothing obvious here to " + verbName + ".\n");
ok := false;
fi;
elif what ~= "" then
name := FormatName(what);
ambig := " is ambiguous here.\n";
st := FindName(Me()@p_pCarrying, p_oName, what);
if st = fail then
st := FindName(here@p_rContents, p_oName, what);
if st = fail then
object := FindAgent(what);
if object = nil then
if here@p_rBuyList ~= nil and
FindName(here@p_rBuyList, p_oName, what) ~= fail
then
done := true;
ok := false;
Print("You should buy the " + name +
" before you try to " + verbName + " it.\n");
elif MatchName(here@p_rScenery, what) ~= -1 then
done := true;
ok := false;
Print(failHeader + " the " + name + ".\n");
fi;
fi;
elif st = continue then
Print(Capitalize(name));
Print(ambig);
ok := false;
done := true;
else
object := FindResult();
name := FormatName(object@p_oName);
fi;
elif st = continue then
Print(Capitalize(name));
Print(ambig);
ok := false;
done := true;
else
object := FindResult();
name := FormatName(object@p_oName);
fi;
if object = nil and not done then
Print(IsAre("There", "no", name, "here.\n"));
done := true;
ok := false;
fi;
fi;
if done then
ok
else
commonVerbTail(direct, indirect, actorCheck,
object, failHeader, verbName, name)
fi
corp;
unuse tp_util2