on_use(button_surface) {
if lift.position == start_node {
begin_move(lift, end_node);
} else if lift.position == end_node {
begin_move(lift, start_node);
} else {
/* do nothing, it's busy already */
}
/* you could also do something different based
* on [i]which[/i] button were pressed */
}
def ManageAction(self, info):Keep in mind that it is a contrived version of the original. Every entity in the game would have that function running on its behalf when it was focusing on an activity.
self.PrepareAndStartAbilities(info.targetID)
self.FollowObject(info.targetID, range=self.targetingRange * 0.9)
self.WaitUntilWithinRange(self.targetingRange * 0.9)
self.AcquireTarget(info.targetID)
while True:
Sleep(1500)
self.CheckAndMaybeFixActionConditions(info)
self.MaybeDoSomeSpecialShit(info)
def ManageAction(self, info):Let's take a look at a possible CheckActionValid:
# This function is not scheduled right after creation so treat the situation
# as if blocking had occurred.
if not self.CheckActionValid(info):
return
self.PrepareAndStartAbilities(info.targetID)
self.FollowObject(info.targetID, range=self.targetingRange * 0.9)
if not self.WaitUntilWithinRange(self.targetingRange):
return # Internal CheckActionValid(info) call.
if not self.AcquireTarget(info.targetID):
return # Internal CheckActionValid(info) call.
# ..
while True:
Sleep(1500)
if not self.CheckActionValid(info):
return
if not self.CheckAndMaybeFixActionConditions(info):
return # Internal CheckActionValid(info) call.
self.MaybeDoSomeSpecialShit(info)
def CheckActionValid(self, actionInfo):The fact is that when you have many objects interacting, and many coroutines possibly interleaved with each other, the potential for unforseen conditions to arise is extremely high. Here's someone else trying to reconcile checking for relevance after blocking. You can read more detail on my thoughts on this matter in his comments (see the long comment that talks about generator coroutines). In order to develop stable code within this model, you need to understand more than just the code you are writing. Even if someone else writes lots of methods like CheckActionValid, chances are the builder is going to be pasting it in religiously, rather than with a proper understanding.
# Superceded by another action. Or the action has been shut down.
if self.actionInfo is not actionInfo:
return False
# Entity is no longer valid. Killed? Removed from game?
if self.released:
return False
if actionInfo.targetID:
# Just in case we did not get notified.
if not self.environment.IsPresent(actionInfo.targetID):
return False
# …
return True
object room1
property description "There is a tree here."
method describe
player:tell description
object room2
property description "There is a tree here. Its leaves glisten in the [day]sunlight[/day][night]moonlight[/night]."
method describe
player:tell(utility:mudmarkup(description))
object room3
property description "There is a tree here."
method describe
if system:time is 'day
player:tell "There is a tree here. Its leaves glisten in the sunlight."
else
player:tell "There is a tree here. Its leaves glisten in the moonlight."
$ @create object room2
$ @addprop room2 description "There is a tree here. Its leaves glisten in the [day]sunlight[/day][night]moonlight[/night]."
$ @addmethod room2 describe player:tell(utility:mudmarkup(description))
room1
description "There is a tree here."
describe
player.tell description
s(:defobj,
:room1,
s(:defprop,
:description,
s(:str, "There is a tree here.")),
s(:defmeth,
:describe,
s(:scope,
s(:call,
s(:global, :player),
:tell,
s(:arglist, s(:ivar, :description))))))
Well discussing program languages is a bit like discussing politics or religion; most people have already made up their minds before they start posting.
I don't think there's any "right" answer to be honest, but I do find it interesting to see the views of people who have actually used one approach or another. In particular, I found it interesting that Orrin uses a lot of scripting and says he's found it more of a hindrance than a help, while I use no scripting and find that to be a hindrance. Is the best solution some sort of balance between the two? Or is it just that the grass is always greener on the other side?