def execInstruction(self, instruction): # returns the next address or -1 if the # loop should be broken def getOffset(self, text): if text[0] == "@": label = text[1:] return self._labels[label] elif text == "end": return len(self._script) + 1 elif text[0] == "+" or text[0] == "-": return self._scriptPtr + int(text) else: return int(text) def push(self, value): self._stack.insert(0, value) def pop(self): if self._stack == []: self.warning("Stack underflow.") return None val = self._stack[0] del self._stack[0] return val token = string.split(instruction) nextPtr = self._scriptPtr + 1 # :dprint <<expression>> # # Print some debugging info in the server stdout. # if token[0] == ":dprint": print "DPRINT[" + self._id + "." + ` self._oid ` + "]:", self.evalExpr(string.join(token[1:])) # :reset # # elif token[0] == ":reset": self.reset() # :write <<expression>> # # Write the expression result into the room. # elif token[0] == ":write": room = self.getLocation() room.writeToRoom(self.evalExpr(string.join(token[1:])) + "\r\n") # :putcookie <<Character>> <cookie> # # Adds a piece of arbitrary string to a character cookie box. # elif token[0] == ":putcookie": char = self.evalExpr(token[1]) char.putCookie(token[2]) # :hascookie <<Character>> <cookie> <command> # # Checks whether the character has the cookie and executes the # command if yes. # elif token[0] == ":hascookie": char = self.evalExpr(token[1]) if char.hasCookie(token[2]): nextPtr = self.execInstruction(string.join(token[3:])) # :removecookie <<Character>> <cookie> # # Removes the cookie from the character's cookie box if it's there. # elif token[0] == ":removecookie": char = self.evalExpr(token[1]) char.removeCookie(token[2]) # :addquest <<Character>> <quest descr> # # Adds a quest description to the character. # elif token[0] == ":addquest": char = self.evalExpr(token[1]) char._quests.append(token[2]) # :removequest <<Character>> <keyword> # # Remove a quest description that contains the keyword from # the character. # elif token[0] == ":removequest": char = self.evalExpr(token[1]) for q in char._quests: if string.find(q, token[2]) >= 0: char._quests.remove(q) break # :do <mud command> <<expression>> # # Execute a MUD command using the expression result as argument. # elif token[0] == ":do": self._commandQueue.append(token[1] + " " + self.evalExpr(string.join(token[2:]))) # :goto <position> | :goto +/- <offset> | :goto end | :goto @label # # Go to another part of the script. # elif token[0] == ":goto": nextPtr = getOffset(self, token[1]) print "goto", nextPtr, self._state # :gosub <position> | :gosub +/-<offset> # # Go to another part of the script and save current position. # Can be returned later into this position with :return. # elif token[0] == ":gosub": push(self, nextPtr) nextPtr = getOffset(self, token[1]) # :return # # Return to a place where a :gosub was called # elif token[0] == ":return": nextPtr = pop(self) # :delay <<seconds>> # # Delay for some time # elif token[0] == ":delay": if self._commandQueue: # must wait the queue to be empty, # so the delay will actually happen return -1 if self._delay == 0: self._delay = self.evalExpr(token[1]) + 1 return -1 else: self._delay = self._delay - 1 if self._delay > 0: return -1 # :wait <event type> [from <<Mobile>>] # # Wait for an event of specified type and optionally # from the specified Mobile. # elif token[0] == ":wait": self._waitingEvent = token[1] if len(token) == 4: if token[2] == "from": self._waitingEventFrom = self.evalExpr(token[3]) return -1 # :on <event> [from <<Mobile>>] <command> # # Set a event handler for the specified event, making it jump to # position when it occurs. # elif token[0] == ":on": event = token[1] if len(token) > 2: if token[2] == "from": mob = self.evalExpr(token[3]) cmd = string.join(token[4:]) else: mob = None cmd = string.join(token[2:]) self._onHandlers[event] = (mob, cmd) else: self._onHandlers[event] = None # :set <identifier> <<expression>> # # Assign expression result into variable # elif token[0] == ":set": self._variables.__dict__[token[1]] = self.evalExpr(string.join(token[2:])) # :match <<string1>> <<string2>> <position> # # Try to match the strings and jump to position if they do. # elif token[0] == ":match": parts1 = string.split(string.lower(self.evalExpr(token[1]))) parts2 = string.split(string.lower(self.evalExpr(token[2]))) if len(parts1) == len(parts2): ok = 1 for i in range(len(parts1)): if parts1[i] != parts2[i]: ok = 0 break if ok: nextPtr = getOffset(self, token[3]) # :speed <seconds> # # Set the speed (delay between commands) of the script to be executed. # elif token[0] == ":speed": self._speed = max(int(token[1]), 1) # :case <<expression>> <<value1>> <pos1> <<value2>> <pos2> ... # :if <<expression>> then <position> # # If result of expression is true, jump to position, else continue. # elif token[0] == ":if": i = token.index("then") if self.evalExpr(string.join(token[1:i])): nextPtr = getOffset(self, token[i + 1]) # :label <identifier> # # Set a label. (handled on startup, so its ignored here) # elif token[0] == ":label": pass # :message <target id> <message> # # Sends a message to a target. # elif token[0] == ":message": event = Event(EVN_MESSAGE, self) event.message = token[2] for m in self._world._mobiles: if m._id == token[1]: m.handleEvent(event) else: self.warning("Invalid command in mob script " + token[0]) return nextPtr