I’m having a bit of trouble with actions. I hate to ask another question so soon, but this should hold me over for awhile. I’m making a SleepOn action. I created the definition, the phrase, and modified thing. The game runs, but it just says it doesn’t understand the command.
All this code does absolutely nothing, lol. Did I spell something wrong, or get an error in the structure?
For the start it should be ‘sleep’ ‘on’ singleDobj and not ‘sleep on’ singleDobj, every word must be treated as a separate token, otherwise it won’t match in parser.
You should define the verb rule with ‘sleep’ ‘on’ (two tokens), not ‘sleep on’ (a single token containing whitespace).
As an aside, note that you may be able to get rid of the gActor().aName == ‘you’ condition using for both cases the syntax: illogical(’{The actor/he} do{es}n’t need rest.’);
Thanks Micheal. I coded a mammoth of structured sloppy butch code, so I’m not sure if doing that would be feesible. I would have to change a lot I should have changed my isHe variable in my player actor, but instead created a gender variable. I also let the players choose a name for name variable I defined… Sorry for being sloppy.
I’m working on a daemon for my sleep, but it’s not working. Can you check this and tell me how I can turn it around?
I modified Thing
modify Thing
dobjFor(SleepOn)
{
verify()
{
if(gActor.sleepBar >= 100)
{
if(gActor.aName() == 'you' || gActor.aName() == 'You')
{
illogical('<<gActor.name>> doesn\'t need rest.');
}else{
illogical('<<gActor.aName>> doesn\'t need rest.');
}
// end if sleepBar >= 100
}
// End Verify SleepOn
}
// End dobjFor SleepOn
action()
{
// make character asleep
// make sleep posture
// effect stats
if(gDobj.sleepable)
{
// character gets good rest
gActor.asleep = true;
gActor.makePosture(sleepingPosture);
if(gActor.aName.toLower == 'you')
{
"<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
// have sleep bar go up by 3 every second (takes roughly 30 seconds)
daemonID = new RealTimeDaemon(gActor, &gActor.sleep_handler(), 30000);
sleepOver = nil;
do{
if(gActor.sleepBar == gActor.maxSleep || !gActor.asleep)
{
// Wake up the characters
// end the sleep daemon
daemonID = nil;
daemonID.removeEvent();
// finished sleeping
}
}while(daemonID)
// have hp gp up by
}else{
"<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
}
}else if(gDobj.name.toLower == 'floor')
{
// character gets slower rest
}else{
// can't sleep on item
if(gActor.aName.toLower == 'you')
{
"<<me.name>> doesn't want to sleep on that.";
}else{
"<<gDobj.aName>> doesn't want to sleep on that.";
}
}
// end sleep on execAction
}
}
// End Modify Thing
;
This line throws an error saying I’m not pointing to a function.
daemonID = new RealTimeDaemon(gActor, &gActor.sleep_handler(), 30000);
Wait, sorry for double posting. I removed the loop because I want to make the daemon more realtime, with a wake command. My sleep_handler function doesn’t get called though.
Modified thing
action()
{
// make character asleep
// make sleep posture
// effect stats
if(gDobj.sleepable)
{
// character gets good rest
gActor.asleep = true;
gActor.makePosture(sleepingPosture);
sleepID = new RealTimeDaemon(gActor, &sleep_handler, 30000);
if(gActor.aName.toLower == 'you')
{
"<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
// have sleep bar go up by 3 every second (takes roughly 30 seconds)
}else{
"<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
}
}else if(gDobj.name.toLower == 'floor')
{
// character gets slower rest
}else{
// can't sleep on item
if(gActor.aName.toLower == 'you')
{
"<<me.name>> doesn't want to sleep on that.";
}else{
"<<gDobj.aName>> doesn't want to sleep on that.";
}
}
// end sleep on execAction
}
sleep handler on actor character
sleep_handler()
{
"sleeping";
}
I should see “sleeping” every 3 seconds?
Does the daemon callback function have to be on the same object the action is on?
I tried the last version of your code by copying it nearly as-is (just replacing the condition gActor.sleepBar >= 100 with nil) in a starter game, and it worked. But I see the daemon message every 30 seconds, not every 3 seconds, because the third argument to RealTimeDaemon is 30 000. Could the longer duration be why it appeared not to work?
You should also declare daemonID somewhere, but ideally not on class, but somewhere global, on player character or such to have only one instance and before creating a new daemon check that it is not running already. Or you risk more daemons at once or losing inaccessible daemon when garbage collector runs.
I’m having some new troubles. I’m trying make the Sleepable class a little more advanced by adding isHard. The problem is is I need to access gDobj in the sleep_handler function. I tried passing it as an argument two different ways. One way game me a formal argument error, and the other is just saying that my set daemon function expects a comma after arguments (as if the parser can’t differentiate between an argument being passed to the handler and the arguments in the demon calling function.)
class Sleepable : Thing
isSleepable = true
isHard = nil
hardWord = ''
// sleep handler
sleep_handler(bed)
{
if(gActor.sleepBar <= 100)
{
gActor.sleepBar += 10;
}
if(!bed.isHard)
{
if(gActor.sleepBar > 100)
{
gActor.sleepBar = 100;
// wake the gActor
// set posture to laying
// cancel sleep daemon
gActor.asleep = true;
gActor.makePosture(lying);
me.sleepDaemon.removeEvent;
"<<one of>><<gActor.name>> wakes, after a good rest. <<me.return_pronoun('he/she', me.gender ,'u')>>
feels much better now.<<or>>After a good rest, <<me.name>> feels much better.";
}
// !isHard in sleep handler
}else{
// isHard in sleep handler
if(gActor.sleepBar >= 60)
{
gActor.sleepBar = 60;
// wake the gActor
// set posture to laying
// cancel sleep daemon
gActor.asleep = true;
gActor.makePosture(lying);
me.sleepDaemon.removeEvent;
"<<one of>><<gActor.name>> wakes resltessly, feeling under rested. <<me.return_pronoun('he/she', me.gender ,'u')>>
After waking <<gActor.name>> wakes, still feeling tired.";
}
// end isHard in sleep handler
}
"Zzz";
"/t <em>sleep +10</em>";
}
dobjFor(SleepOn)
{
verify()
{
if(gActor.sleepBar >= 100)
{
if(gActor.aName() == 'you' || gActor.aName() == 'You')
{
illogical('<<gActor.name>> doesn\'t need rest.');
}else{
illogical('<<gActor.aName>> doesn\'t need rest.');
}
// end if sleepBar >= 100
}
// End Verify SleepOn
}
// End dobjFor SleepOn
action()
{
if(gDobj.isSleepable)
{
if(!gDobj.isHard)
{
// character gets good rest
gActor.asleep = true;
gActor.makePosture(sleepingPosture);
me.sleepDaemon = new RealTimeDaemon(self, &sleep_handler(gDobj), 3000);
if(gActor.aName.toLower == 'you')
{
"<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
// have sleep bar go up by 3 every second (takes roughly 30 seconds)
}else{
"<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
}
// End if Sleepable not hard
}else{
// Character gets bad rest
gActor.asleep = true;
gActor.makePosture(sleepingPosture);
me.sleepDaemon = new RealTimeDaemon(self, &sleep_handler(gDobj), 10000);
if(gActor.aName.toLower == 'you')
{
"<<me.name>> plunks down on the <<gDobj.hardWord>> <<gDobj.name>> and falls asleep.";
// have sleep bar go up by 3 every second (takes roughly 30 seconds)
}else{
"<<gDobj.aName>> lays on the <<gDobj.hardWord>> <<gDobj.name>> and sleeps.";
}
// end if Sleeple is hard
}
}else if(gDobj.name.toLower == 'floor')
{
// character gets slower rest
}else{
// can't sleep on item
if(gActor.aName.toLower == 'you')
{
"<<me.name>> doesn't want to sleep on that.";
}else{
"<<gDobj.aName>> doesn't want to sleep on that.";
}
}
// end sleep on execAction
}
}
;
There is no way to pass an argument in new RealTimeDaemon(self, &sleep_handler, 3000) statement, because you are not calling the handler here. You are calling RealTimeDaemon constructor and passing a reference to sleep_handler function. Sleep_handler is so called “callback function” which is called by the daemon on an occasion and not by you. And the daemon is not willing to pass any arguments.
But you can overcome this limitation in other way. For example similar as you set gActor.asleep = true; create an additional property on actor and try to gActor.sleepingOn = gDobj or me.sleepingOn = gDobj. Then you can read these properties from the callback.
Also you shouldn’t depend on gActor in the callback. gActor is a macro expanding to actor of currently processed action and it is not necessary defined once the action processing ends or even can change on subsequent commands from the player as the RealTimeDaemon wakes up on some real time occasions. When you are in action() phase copy gActor value somewhere and use this copy from callback.
If it works then it’s probably fine. I’m just not sure whatever there are more actors that could sleep in your game or just the player and if so whatever more then one actor can sleep at any given time. Class properties are copied for every object of that class, so every Sleepable object has the property isHard, which is what you want, but it would be more logical to locate daemon property to player object.
Also I’ve noticed you are referring gDobj in action() of Sleepable: if(gDobj.isSleepable) and if(!gDobj.isHard) which is unnecessary, you are on Sleepable object so you don’t need isSleepable test and you can shorten second test to only if(!isHard). Also gActor.aName.toLower == ‘you’ could be shortened to gActor == me, if(gDobj.name.toLower == ‘floor’) to if(gDobj.ofKind(Floor)).
Okay, I fixed some of the errors you suggested. I’m interested in having multiple characters be able to sleep, even if in a different game. I’ve got sleep_handler on Sleepable, and store the sleepDaemon on the player. Tell me if this looks alright so far, or am I in the right ball park?
class Sleepable : Thing
isSleepable = true
isHard = nil
hardWord = ''
// sleep handler
sleep_handler()
{
if(gActor.sleepBar <= 100)
{
gActor.sleepBar += 10;
}
if(gActor == me)
{
"Zzz \n";
"\t <em>sleep +10</em>\n";
}else{
if(gActor.reportSleep)
{
"Zzz \n";
"\t <em>sleep +10</em>\n";
}
}
gActor.wakeIssued = true;
if(!self.isHard)
{
if(gActor.sleepBar > 100)
{
gActor.sleepBar = 100;
// wake the gActor
// set posture to laying
// cancel sleep daemon
gActor.asleep = nil;
gActor.makePosture(lying);
gActor.sleepDaemon.removeEvent;
"\b<<one of>><<gActor.name>> wakes, after a good rest. <<me.return_pronoun('he/she', me.gender ,'u')>>
feels much better now.<<or>>After a good rest, <<me.name>> feels much better.<<end>>";
}
// !isHard in sleep handler
}else{
// isHard in sleep handler
if(gActor.sleepBar >= 60)
{
gActor.sleepBar = 60;
// wake the gActor
// set posture to laying
// cancel sleep daemon
gActor.asleep = nil;
gActor.makePosture(lying);
gActor.sleepDaemon.removeEvent;
"\b<<one of>><<gActor.name>> wakes resltessly, feeling under rested. <<me.return_pronoun('he/she', me.gender ,'u')>>
After waking <<gActor.name>> wakes, still feeling tired.<<end>>";
}
// end isHard in sleep handler
}
// end sleep handler
}
dobjFor(SleepOn)
{
verify()
{
if(gActor.sleepBar >= 100)
{
if(gActor == me)
{
illogical('<<gActor.name>> doesn\'t need rest.');
}else{
illogical('<<gActor.aName>> doesn\'t need rest.');
}
// end if sleepBar >= 100
}
// End Verify SleepOn
}
// End dobjFor SleepOn
action()
{
if(gDobj.isSleepable)
{
if(!gDobj.isHard)
{
// character gets good rest
gActor.asleep = true;
gActor.makePosture(sleepingPosture);
gActor.sleepDaemon = new RealTimeDaemon(self, &sleep_handler, 3000);
if(gActor == me)
{
"<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
// have sleep bar go up by 3 every second (takes roughly 30 seconds)
}else{
"<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
}
// End if Sleepable not hard
}else{
// Character gets bad rest
gActor.asleep = true;
gActor.makePosture(sleepingPosture);
gActor.sleepDaemon = new RealTimeDaemon(self, &sleep_handler, 10000);
if(gActor == me)
{
"<<me.name>> plunks down on the <<gDobj.hardWord>> <<gDobj.name>> and falls asleep.";
// have sleep bar go up by 3 every second (takes roughly 30 seconds)
}else{
"<<gDobj.aName>> lays on the <<gDobj.hardWord>> <<gDobj.name>> and sleeps.";
}
// end if Sleeple is hard
}
}else if(gDobj.ofKind(Floor))
{
// character gets slower rest
}else{
// can't sleep on item
if(gActor == me)
{
"<<me.name>> doesn't want to sleep on that.";
}else{
"<<gDobj.aName>> doesn't want to sleep on that.";
}
}
// end sleep on execAction
}
// end dobjFor SleepOne
}
;