!! Multiplayer Inform 0.1 for ifMUD's Floyd Copyright 1999 Evin Robertson.
!! May be used, modified, and distributed without restriction. Absolutely no
!! warranty of any type is provided for this library.
!!
!! Very loosely based on Adam Cadre's multistub.h. Uses bits of the name
!! parsing code in Graham Nelson's _Balances_. Thanks to Jota for some
!! insane ideas which eventually developed into Floyd.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! You should remove the line !!
!! if (o==player) { print (string) YOURSELF__TX; rtrue; } !!
!! from parserm.h to obtain correct output. !!
!! !!
!! Disambiguation isn't yet properly fixed, so add the line !!
!! best_etype = NO_DISAMB_PE; rfalse; !!
!! to parserm.h immediately before the line !!
!! if (match_from > num_words) jump Incomplete !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! You can either take existing games and fit them to this library or write a
!! new game to use this library. To fit an existing game to multifloyd,
!! include this header between Parser and VerbLib. Rename the game's
!! Initialise to GameInitialise. You may want to provide a 'multiobject' for
!! the game - see the example given in werewolf. To write a game specifically
!! for floyd, either study the werewolf source or wait for me to to write a
!! proper manual.
!! TODO:
!! * Fix disambiguation by copying each player's input to their player object
!! and refeeding the library, blocking its questions the second time
!! * Make each player die separately
!! * Write a bridge game to demonstrate turn-taking
!! * Write an IF game to demonstrate actions visible to other players in the
!! same room
!! * Write better documentation
#IFNDEF multiobject;
Object multiobject;
#ENDIF;
Replace YesOrNo;
[ YesOrNo i;
for(::) {
read buffer parse;
i=parse-->5; !! Look at third word instead of first
if (i==YES1__WD or YES2__WD or YES3__WD) rtrue;
if (i==NO1__WD or NO2__WD or NO3__WD) rfalse;
L__M(##Quit,1); print "> ";
}
];
[ BeforeParsing src dest word_space i;
PersonThisTurn = find_player(1); !! First word is name of person
if(parse->1 == 3 && ParseWordNumber(3) == 'abort')
quit;
if(~~PersonThisTurn) {
if(parse->1 == 3)
switch(ParseWordNumber(3)) {
'join': Addplayer(); jump ignorecommand;
'who': WhoSub(); jump ignorecommand;
'quit': quit;
}
print "<whisper ";
for(i = 0: i < WordLength(1): i++)
print (char) WordAddress(1)->i;
print ">";
if(~~(multiobject provides orders &&
multiobject.orders(ParseWordNumber(3))))
print "You must be a player to enter a command.^";
print "</whisper>";
.ignorecommand;
parse->1 = 1; (parse+2)-->0 = ',donothing';
return;
}
ChangePlayer(PersonThisTurn); !! Make this that person
last_score = score = PersonThisTurn.player_score;
parse->1 = parse->1 - 2; !! Chop off first two words
word_space = (parse->1) * 4;
src = parse + 10;
dest = parse + 2;
@copy_table src dest word_space;
won(PersonThisTurn);
];
Show:
if(AfterRoutines()~=1)
print "You show ", (the) noun, " to ", (the) self, ".^";
won(self);
o = player;
ChangePlayer(self);
<examine noun>;
ChangePlayer(o);
woff();
rtrue;
Ask, Tell, Answer:
won(self);
print (name) actor;
switch(action) {
##Ask: print " asks you about ";
##Tell: print " tells you about ";
##Answer: print " tells you, ";
}
message = WordAddress(consult_from);
len = WordAddress(consult_from + consult_words - 1) - message +
WordLength(consult_from + consult_words - 1);
for(i = 0: i < len: i++)
print (char) message->i;
new_line;
woff();
print_ret (The) self, " pretends to pay attention.";
Order:
won(self);
print (The) actor, " enslaves you [BUG].^";
woff();
"You turn ", (the) self, " into your slave [BUG].";
default:
won(self);
print (The) actor, " performs wacky antics with you [BUG].^";
woff();
"You perform wacky antics with ", (the) self, " [BUG].";
],
last_location 0,
react_before [;
if(actor ~= self)
rfalse;
switch(action) {
##Go: self.last_location = location;
}
],
react_after [ o s n;
if(actor == self) {
if(action == ##Go or ##Enter or ##Exit) {
objectloop(o in self.last_location && o has ingame && o ~= self) {
won(o);
print (name) self, " goes ";
LanguageDirection(noun.door_dir);
print ".^";
woff();
}
}
rfalse;
}
s = second; n = noun;
if(second == self)
s = youobject; !! Make it say 'you' for the destination
if(noun == self)
n = youobject;
won(self);
switch(action) {
##Go:
print (The) actor, " arrives from ", (opposite_dir) n.door_dir, ".^";
##Enter:
print (The) actor, " goes into ", (the) n, ".^";
##Exit:
print (The) actor, " exits.^";
##Take:
print (The) actor, " takes ", (the) n, ".^";
##Drop:
print (The) actor, " drops ", (the) n, ".^";
##Remove:
print (The) actor, " removes ", (the) n, " from ", (the) s, ".^";
##PutOn:
print (The) actor, " puts ", (the) n, " on ", (the) s, ".^";
##Insert:
print (The) actor, " puts ", (the) n, " in ", (the) s, ".^";
##Examine:
print (The) actor, " examines ", (the) n, ".^";
##Search:
print (The) actor, " searches ", (the) n, ".^";
##ThrowAt:
print (The) actor, " throws ", (the) n, " at ", (the) s;
if(s == youobject)
print " and you catch it";
else if(s has ingame)
print ", who catches it";
print ".^";
##Give:
print (The) actor, " gives ", (the) s, " ", (the) n, ".^";
##Show:
print (The) actor, " shows ", (the) s, " ", (the) n, ".^";
##Kiss:
print (The) actor, " kisses ", (the) n, " on the cheek.^";
##WakeOther:
print (The) actor, " tries but fails to wake ", (the) n, " up.^";
##Attack:
print (The) actor, " makes menacing glances at ", (the) n, ".^";
##Unlock:
print (The) actor, " unlocks ", (the) n, ".^";
##Lock:
print (The) actor, " locks ", (the) n, ".^";
##SwitchOn:
print (The) actor, " turns on ", (the) n, ".^";
##SwitchOff:
print (The) actor, " turns off ", (the) n, ".^";
##Open:
print (The) actor, " opens ", (the) n, ".^";
##Close:
print (The) actor, " closes ", (the) n, ".^";
##Disrobe:
print (The) actor, " takes off ", (the) n, ".^";
##Wear:
print (The) actor, " puts on ", (the) n, ".^";
##Eat:
print (The) actor, " eats ", (the) n, ".^";
}
woff();
],
player_score,
number, !! Required for player objects
has animate neuter proper light;
[ TextReader point i len; ! Mostly from balances
for(i=0: i<PlayerNameMax: i++)
text_buffer->i = 0;
if(wn > parse->1) {
wn++;
rfalse;
}
point = WordAddress(wn);
len = WordLength(wn);
if(len > PlayerNameMax)
len = PlayerNameMax;
for(i=0: i<len: i++)
text_buffer->i = point->i;
wn++; rtrue;
];
Object noplace "Waiting for players to join"
with description [;
print "WHO: Who's already playing?^JOIN: Add me to the list of players!^QUIT: Scratch me from the list of players!^ABORT: Make the game quit^";
if(multiobject provides description)
multiobject.description();
],
has light;
[ Initialise;
location = noplace;
lookmode = 2; !! default to verbose mode - difficult to keep track of
!! visited rooms separately for each player