This is long and… miscellaneous. I have three issues, the first two are probably dumb and quick but require explanation of what I’m doing. The third one I don’t know where to begin…
First problem: Remapping actions to other actions:
[rant]I wanted a small water spring from which you could drink:
spirngArea: OutdoorRoom 'Forest Spring'
;
+spring: Fixture 'divine holy water/spring/pool' 'water spring'
"A water spring"
;
Then I messed with the dobjFor(Drink) so you could actually drink from it:
+spring: Fixture 'divine holy water/spring/pool' 'water spring'
"A water spring"
dobjFor(Drink)
{
preCond = []
verify() {}
action()
{
"You drank from the spring. ";
}
}
;
THEN I realized I wanted to make sure additional verb inputs like “drink from spring” and “drink water from spring” worked, so I created two new actions:
[code]
DefineTAction(DrinkFrom)
;
VerbRule(DrinkFrom)
(‘drink’ | ‘quaff’ | ‘imbibe’)
(‘from’ | ‘out’ ‘of’ | ‘off’ | ‘off’ ‘of’) dobjList
: DrinkFromAction
verbPhrase = ‘drink/drinking (what)’
;
DefineTIAction(DrinkXFrom)
;
VerbRule(DrinkXFrom)
(‘drink’ | ‘quaff’ | ‘imbibe’) dobjList
(‘from’ | ‘out’ ‘of’ | ‘off’ | ‘off’ ‘of’) singleIobj
: DrinkXFromAction
verbPhrase = ‘drink/drinking (what)’
;[/code]
Aaaand here’s where I probably went crazy: The only way I could figure out for these two actions to have the exact same effect as Drink was to copy the exact same code three times, so the spring object ends up looking like this:
+spring: Fixture 'divine holy water/spring/pool' 'water spring'
"A water spring"
dobjFor(Drink)
{
preCond = []
verify() {}
action()
{
"You drank from the spring. ";
}
}
dobjFor(DrinkFrom)
{
preCond = []
verify() {}
action()
{
"You drank from the spring. ";
}
}
dobjFor(DrinkXFrom)
{
preCond = []
verify() {}
action()
{
"You drank from the spring. ";
}
}
;
I get the feeling that there should probably be a tidier way to do this, but I can’t figure out how to make Remap work for me here.[/rant]
Second and third problems are about Wearables, or rather my custom class of Wearables, called Equipment. This first one has to do with default message responses. Here’s the gist of the code:
[rant][code]class Equipment: Wearable
dobjFor(Wear)
{
preCond = [objHeld]
verify()
{
if (isWornBy(gActor))
illogicalAlready(&alreadyWearingMsg);
}
action()
{
equipAlterStats();
makeWornBy(gActor);
defaultReport(&okayWearMsg);
}
}
dobjFor(Doff)
{
preCond = [roomToHoldObj]
verify()
{
if (!isWornBy(gActor))
illogicalAlready(¬WearingMsg);
else
logicalRank(150, ‘worn’);
}
action()
{
unequipAlterStats();
makeWornBy(nil);
defaultReport(&okayDoffMsg);
}
}
equipAlterStats()
{
gPlayerChar.ATK += ATK;
}
unequipAlterStats()
{
gPlayerChar.ATK -= ATK;
}
;
class Weapon: Equipment
okayWearMsg = "You are now wielding <>. "
alreadyWearingMsg = "You are already wielding <>. "
notWearingMsg = "You are not currently wielding <>. "
okayDoffMsg = "You are no longer wielding <>. "
;
dagger: Weapon ‘steel small rusted knife/dagger’ ‘rusted dagger’ @springArea
"It’s a small rusted dagger. "
ATK = 10
;[/code]
The main point of this mess is to have the (still very unfinished) equipAlterStats() and unequipAlterStats() methods executed when the objects are equipped or unequipped, thus having the typical effect of RPG equipment: altering stats. The point of the subClass Weapon is to customize the messages according to the type of object (You wield a weapon, but you’d wear an armor and so on). It all works pretty well except for illogicalAlready(&alreadyWearingMsg) and illogicalAlready(¬WearingMsg), since these already print their own “you are already…” messages, so the output ends up looking as:
equip dagger
(first taking the rusted dagger)
You are now wielding the rusted dagger.
equip dagger
You are already wielding the rusted dagger. You’re already wearing it.
unequip dagger
You are no longer wielding the rusted dagger.
unequip dagger
You are not currently wielding the rusted dagger. You’re not wearing that.
The parts in bold are redundant and I can’t figure out how to get rid of them.[/rant]
The third issue… I don’t even know where to begin. The aim here is to no allow for more than a single sample of each type of equipment to be equipped at once. So if an item from the Weapon class (like the dagger above) is equipped and the player tries to Equip another Weapon item, like say:
[rant]sword: Weapon 'steel rusted sword/blade' 'rusted sword' @springArea
"It's a small rusted blade. "
ATK = 10
;
I’d want the game to automatically unequip the dagger and equip the sword.
The macro bcressey showed me before…
#define MakeClassList(K, N) \
##N : object \
\
lst() \
{ \
if (lst_ == nil) \
initLst(); \
return lst_; \
} \
\
initLst() \
{ \
lst_ = new Vector(50); \
local obj = firstObj(); \
while (obj != nil) \
{ \
if(obj.ofKind(##K)) \
lst_.append(obj); \
obj = nextObj(obj); \
} \
lst_ = lst_.toList(); \
} \
\
indexOf(val) \
{ \
if (lst_ == nil) \
initLst(); \
return lst_.indexOf(val); \
} \
\
indexWhich(func) \
{ \
if (lst_ == nil) \
initLst(); \
return lst_.indexWhich(func); \
} \
\
subset(func) \
{ \
if (lst_ == nil) \
initLst(); \
return lst_.subset(func); \
} \
\
lst_ = nil \
…allows me to create a list with all Weapon-class objects via MakeClassList(Weapon, allWeapons), but I can’t figure out a way to use it in away that I could add a check so that, upon trying to execute the (customized above) dobjFor(Wear) action of one of these Weapons, it’d check if any other objects of its class are already being worn, and if so, would execute that respective object’s (customized) dobjFor(Doff) action. If that’s not doable, I’d settle for simply stopping the Wear action and having the player manually unequip the Weapon before equipping the new one. This is… probably because I don’t actually understand how to use the macro’s lists, I just rolled with the code bcressey handed me already made when I used it for rooms and now I’m paying the price of using code I don’t even understand fully.[/rant]