Ejemplo n.º 1
0
 def handle_OPENDOOR(self, action, data, id):
     dir = data.lower()
     if not G.rooms[self.char.loc].open[dir]:
         G.rooms[self.char.loc].open[dir] = True
         px, py, pz = self.char.loc
         mx, my, mz = Constant.sdirections[dir]
         G.rooms[(px+mx,py+my,pz+mz)].open[Constant.invert[dir]] = True
         coms.sendRoom(self.char.loc, Ascii.C.format % ("gray", "The door to the %s opens." % (Constant.tolong[dir],)), [])
         coms.sendRoom((px+mx,py+my,pz+mz), Ascii.C.format % ("gray", "The door to the %s opens." % (Constant.tolong[Constant.invert[dir]],)), [])
Ejemplo n.º 2
0
    def AIBrain(self):
        startt = time.time()
        cm = self.cm
        # adjust our think time depending if we have agro until we no longer have agro
        # check if there are people in the room with us
        # if we are ranged check if there are people within range
        if self.cm.isdead:    ##### Dead (5 second think time)
            # we are dead, put us to sleep
            self.sleep()
        else: ##### AGRO CHECK
            if not self.cm.agro:
                self.addAgroRoom()
                
            agro = {}
            # sort a list of targets, apply our modifier and choose the highest on my list
            for target, value in cm.agro.iteritems():
                # treat things in the room with us as 150% agro
                agro[target] = (value * 1.5) if (G.chars[target].loc if target in G.chars else G.monster_live[target].loc) == cm.loc else value
                    
            agros = sorted(agro.iteritems(), key=operator.itemgetter(1))
            ##### Check to see if we want to move
            if not len(agros) and not self.cm.dir and (random.randint(1,100) <= int(self.cm.wander * 100)):
                # wander
                dirs = []
                for dir in G.rooms[self.cm.loc].exit:
                    if G.rooms[self.cm.loc].exit[dir] == 1:
                        dirs.append(dir)
                if dirs:
                    random.shuffle(dirs)
                    dir = dirs.pop()
                    self.DoMove((Constant.tolong[dir], None))
            acted = False
            while not acted and len(agros):
                target, value = agros.pop()
                target = (G.chars[target] if target in G.chars else G.monster_live[target])
                if target.isdead or target.state == CState.OFFLINE:
                    logging.debug("AI; monster %s (%s); target; %s; dead or offline", cm.m.name, cm.uid, target.name)
                    continue
                else:
                    for e in target.effects:
                        if "SYSINVIS" in e.adjust:
                            char.hideDC = 666
                            break
                    if target.hideDC == 0 or (target.hideDC <= self.cm.rollSkill("perception", 5)):
                        logging.debug("AI; monster %s (%s); target; %s; in combat; %s", cm.m.name, cm.uid, target.name, cm.incombat)
                    else:
                        logging.debug("AI; monster %s (%s); target; %s; in combat; %s; target hidden", cm.m.name, cm.uid, target.name, cm.incombat)
                        continue
                
                if target.name in G.chars or target.uid in G.monster_live:
                    # check rooms
                    mx, my, mz = cm.loc
                    px, py, pz = target.loc
                    
                    for dir, add in Constant.sdirections.iteritems():
                        if (cm.loc == target.loc):
                            if cm.target != (target.name if target.__class__.__name__ == 'char' else target.uid) or not cm.incombat:
                                ##### Target this player
                                cm.target = (target.name if target.__class__.__name__ == 'char' else target.uid)
                                cm.incombat = True
                                cm.engaged = True
                                cm.cround = G.round
                                target.incombat = True
                                target.avatar.protocol.sendStat.combat(target.avatar.protocol, True)
                                if not target.target:
                                    target.target = cm.uid
                                target.cround = G.round 
                                # send a moves to attack message to the room
                                logging.debug("AI; monster %s (%s); attacking; %s", cm.m.name, cm.uid, target.name)
                                self.RoomMessage("%s %s %s moves to attack %s!" % (cm.dsc, cm.pname, cm.m.name, target.name), cm.loc, (target.avatar,))
                                self.DirectMessage("%s %s %s moves to attack you!" % (cm.dsc, cm.pname, cm.m.name), target)
                            # parse spells
                            for chance, s in cm.m.spells:
                                self.DoSpell(s, chance)
                            acted = True
                            break
                        ax, ay, az = add
                        if G.rooms[cm.loc].exit[dir] and ((mx+ax == px and my+ay == py and mz+az == pz)) and G.rooms[(mx+ax,my+ay,mz+az)].areaid == cm.area:
                            # Don't move if you are ranged
                            if not cm.m.reach:
                                logging.debug("AI; monster %s (%s); found target; %s; adjacent room %s; moving", cm.m.name, cm.uid, target.name, Constant.tolong[dir])
                                acted = self.DoMove((Constant.tolong[dir], target))
                            else:
                                logging.debug("AI; monster %s (%s); found target; %s; adjacent room %s; reach; %s", cm.m.name, cm.uid, target.name, Constant.tolong[dir], cm.m.reach)
                                if (not cm.target or not cm.target == target.name or not cm.incombat):
                                    acted = True
                                    # target this player from a range
                                    cm.target = target.name
                                    cm.incombat = True
                                    cm.engaged = True
                                    cm.cround = G.round
                                    target.cround = G.round 
                                    target.incombat = True
                                    target.avatar.protocol.sendStat.combat(target.avatar.protocol, True)
                                    if not target.target:
                                        target.target = cm.uid
                                    # send a moves to attack message to the room
                                    logging.debug("AI; monster %s (%s); attacking ranged; %s; %s", cm.m.name, cm.uid, Constant.tolong[dir].title(), target.name)
                                    dsc = "an" if (cm.pname and cm.pname[0].lower() in Constant.vowels) else "a"
                                    self.RoomMessage("%s %s %s moves to attack %s, to the %s!" % (dsc, cm.pname, cm.m.name, target.name, Constant.tolong[dir].title()), cm.loc, (target.avatar,))
                                    self.DirectMessage("%s %s %s moves to attack you, from the %s!" % (dsc, cm.pname, cm.m.name, Constant.invert(Constant.tolong[dir])), target)
                                # parse spells
                                for s, chance in cm.m.spells:
                                    self.DoSpell(s, chance)
                            break
                    # try to follow their tracks (we need to be smart to track)
                    else:
                        if G.tracks.has_key(cm.loc):
                            for name, dir, round in G.tracks[cm.loc]:
                                if name == target.name:
                                    # DC is 5 * rounds old
                                    # basic track score is d10 + (ING * 2) so -2 is 6 (1 round) and +5 is 20 (3 rounds)
                                    if int(random.randint(1, 10) + (cm.m.stat["ING"] * 2)) >= int((G.round - round) * 5):
                                        # found you bitch
                                        logging.debug("AI; monster %s (%s); following tracks; %s; %s", cm.m.name, cm.uid, dir, target.name)
                                        acted = self.DoMove((dir, target))
                                        break
                            else:
                                logging.debug("AI; monster %s (%s); lost trail; %s", cm.m.name, cm.uid, target.name)
                                
                if acted:
                    break

            if not acted and not cm.incombat and self.awake:
                if cm.srounds < 2:
                    cm.srounds += 1
                    logging.debug("AI; We didn't act, strike %s", cm.srounds)
                else:
                    # umm, I lost the trail
                    # are we at home?
                    if not cm.loc == cm.sloc:
                        # start walking back home
                        if not cm.dir:
                            mstartt = time.time()
                            maze = {}
                            for key, r in G.rooms.iteritems():
                                if r.areaid == G.rooms[cm.sloc].areaid:
                                    maze[key] = r
                            ms = MazeSolver(maze)
                            solved_maze = ms.Astar(cm.loc, cm.sloc)
                            cm.dir = solved_maze
                            mendt = time.time()
                            logging.debug("AI; Calculated directions home in %.6f seconds; %s", (mendt - mstartt), solved_maze)
                            dir = cm.dir.pop(0)
                            self.DoMove((dir, None))
                        else:
                            logging.debug("AI; Directions left; %s", cm.dir)
                            dir = cm.dir.pop(0)
                            self.DoMove((dir, None))
                    else:
                        if self.awake == True:
                            #reset us
                            self.cm.reset()
                            self.sleep()
                            # we reset and we were forced spawned, destroy us
                            if not self.cm.spawn_chance:
                                self.cm.isdead = True
                                coms.sendRoom(self.cm.loc, self.cm.m.message["death"].text % (self.cm.name,))
            else:
                cm.srounds = 0 #reset our idle rounds
Ejemplo n.º 3
0
 def doChain(self, chain=None):
     # is there text in this chain?
     nextlink = None
     chain = chain if chain else self.start
     if chain.text and chain.words:
         self.msg = chain.text
         
     if chain.rmsg and chain.words:
         self.rmsg = chain.rmsg # % (Ascii.C.format % ("bwhite", self.char.name))
         
     if chain.text and not chain.words:
         if self.monster:
             self.char.avatar.protocol.sendLine(Ascii.C.format % ("gray", "%s says, '%s'" % (self.monster.name, chain.text)), True)
         else:
             self.char.avatar.protocol.sendLine(Ascii.C.format % ("gray", "%s" % (chain.text)))
         self.default = False
     if chain.rmsg and not chain.words:
         if self.monster:
             coms.sendRoom(self.char.loc, Ascii.C.format % ("gray", "%s says to %s, '%s'" % (self.monster.name, Ascii.C.format % ("bwhite", self.char.name), chain.rmsg)), [self.char.avatar,], True)
         else:
             coms.sendRoom(self.char.loc, Ascii.C.format % ("gray", chain.rmsg % (Ascii.C.format % ("bwhite", self.char.name))), [self.char.avatar,])
         self.default = False
     
     # grab the words and store them
     if chain.words:
         for word in chain.words.split(","):
             w, sep, link = word.partition(":")
             self.words.append((w,int(link)))
             
     if chain.test:
         try:
             thetest = eval(chain.test,{"__builtins__":None},{"char":self.char,"room":G.rooms[self.char.loc]})
             logging.debug("dialogchain; %s; %s; eval; %s", chain.id, chain.test, thetest)
         except Exception as e:
             logging.debug("dialogchain; %s; %s; except; %s", chain.id, chain.test, e.args)
             thetest = False
         if thetest and chain.tpass:
             self.doLink(chain.tpass, chain.id)
         elif not thetest and chain.tfail:
             self.doLink(chain.tfail, chain.id)
         
     # check for a keyword match
     if self.keyword and not self.kwmatch:
         for word, link in self.words:
             if word.startswith(self.keyword):
                 # clear our message, we should follow a keyword
                 self.kwmatch = True
                 self.doLink("dialogchain %s;" % (link,), chain.id)
                 break
     elif chain == self.start and self.default:
         if self.monster:
             self.char.avatar.protocol.sendLine(Ascii.C.format % ("gray", "%s says, '%s'" % (self.monster.name, self.msg)), True)
             coms.sendRoom(self.char.loc, Ascii.C.format % ("gray", "%s says to %s, '%s'" % (self.monster.name, Ascii.C.format % ("bwhite", self.char.name), self.rmsg)), [self.char.avatar,], True)
         else:
             if self.msg:
                 self.char.avatar.protocol.sendLine(Ascii.C.format % ("gray", "%s" % (self.msg)))
             if self.rmsg:
                 coms.sendRoom(self.char.loc, Ascii.C.format % ("gray", self.rmsg % (Ascii.C.format % ("bwhite", self.char.name))), [self.char.avatar,])
     
     logging.debug("dialogchain; %s; end", chain.id)
     return self.kwmatch