示例#1
0
    def initTotals(self, events):
        """ get total tires/avalanches """
        self._totalTires = 0
        self._totalAvalanches = 0

        # detect number of avalanches
        self._totalAvalanches = sum(
            a['turns'] for a in eventDbMatch(events, {'bb_code': "avalanche"}))
        self._totalTires = sum(
            t['turns'] for t in eventDbMatch(events, {'bb_code': "tire"}))
        self.log("Detected {} avalanches".format(self._totalAvalanches))
        self.log("Detected {} tire tosses".format(self._totalTires))
示例#2
0
 def initTotals(self, events):
     """ get total tires/avalanches """
     self._totalTires = 0
     self._totalAvalanches = 0
     
     # detect number of avalanches
     self._totalAvalanches = sum(a['turns'] 
                                 for a in eventDbMatch(events, 
                                                 {'bb_code': "avalanche"}))
     self._totalTires = sum(t['turns'] 
                            for t in eventDbMatch(events, 
                                                  {'bb_code': "tire"}))
     self.log("Detected {} avalanches".format(self._totalAvalanches))
     self.log("Detected {} tire tosses".format(self._totalTires))                
示例#3
0
    def initialize(self, state, initData):
        events = initData['events']
        self._db = initData['event-db']
        self._chatStrings = {
            d['heap_code']: d['chat']
            for d in self._db if d['heap_code']
        }
        self._unstenchStrings = [
            d['chat'] for d in self._db if d['heap_code'] == "unstench"
        ]

        self._heapDone = False
        self._open = state['open']
        self._numDives = sum(
            d['turns'] for d in eventDbMatch(events, {'heap_code': "dive"}))

        self._totalStench = (
            4 +
            sum(t['turns']
                for t in eventDbMatch(events, {'heap_code': "trashcano"})) +
            sum(t['turns']
                for t in eventDbMatch(events, {'heap_code': "stench"})) -
            sum(f['turns']
                for f in eventDbMatch(events, {'heap_code': "unstench"})))
        self._initStench = self._totalStench
        self.log("OldDives: {}, NewDives: {}".format(state['dives'],
                                                     self._numDives))
        self.log("Detected {} trashcanos".format(self._totalStench - 4))

        if state['dives'] == self._numDives and state['stench'] is not None:
            # there have been no trashcanos since we went online
            # add stench difference
            self._stench = (state['stench'] + self._totalStench -
                            state['totalstench'])
            self.log("Restored stench state to {}".format(self._stench))
        elif (state['dives'] != self._numDives
              and state['totalstench'] == self._totalStench):
            # there has been a dive, but no other trashcanos
            self._stench = 0
            self.log("Restored stench state to 0, dives present without "
                     "any more stench")
        else:
            # there have been dives and more trashcanos
            self._stench = None
            self.log("...but it doesn't matter because we can't "
                     "tell when the last treasure dive was")
        self._heapLastNotify = self._stench
        self._processLog(initData)
示例#4
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        if self.getCageState() in [UNKNOWN, EMPTY]: # don't know cage status
            self._inCageFreedTime = None
        else:
            if self._updateInCageActions:
                self._updateInCageActions = False
                self._inCageHoboActions = self.getHoboActions(
                                        self.inCage, events)
                self.log("{} action count = {}".format(
                                        self.inCage, self._inCageHoboActions))
 
            # check if cage occupant has adventured in hobopolis
            currentHoboActions = self.getHoboActions(self.inCage, events)
            if currentHoboActions != self._inCageHoboActions:
                self.log("Detected {} escape: {} -> {}"
                         .format(self.inCage, self._inCageHoboActions, 
                                 currentHoboActions))
                self.chat("{} has left the C.H.U.M. cage.".format(self.inCage))
                self.setEscaped()
                    
        # check sewer actions
        newTotalFreed = sum(
                f['turns'] for f in eventDbMatch(
                    events, {'sewer_code': "rescue"}))
        if newTotalFreed > self._totalFreed and self.getCageState() == TRAPPED:
            self.setReleased(self.inCage)
        self._totalFreed = newTotalFreed
        self._totalSewerActions = sum(
                s['turns'] for s in events if s['category'] == "Sewers")
        return True
示例#5
0
 def initialize(self, state, initData):
     events = initData['events']
     
     # see number of scarehobos killed
     self._killed = sum(k['turns'] for k in eventDbMatch(
                            events, {'town_code': "combat"}))
     self._scareHoboDamage = state['damage']
     killDiff = self._killed - state['killed']
     
     # let's see if any scarehobos look like they were created 
     # (indicated by a decrease in parts)    
     self._guessState = state['scareHoboState']
     if killDiff > 50:
         # we missed some hobo activity, let's say the state is guessed
         # for good measure
         self._guessState = GUESSED
     self._scareHoboParts = self.getParts()
     if self._scareHoboParts is None:
         # usually, this only happens if we are in between instances
         self._scareHoboParts = state['scareHoboParts']
         self._guessState = GUESSED
     
     scareHobos = scareHobosCreated(state['scareHoboParts'], 
                                    self._scareHoboParts)
     self._scareHoboDamage = state['damage']
     if scareHobos > 0:
         guessText = ""
         if self._guessState == GUESSED:
             guessText = " (changing state to GUESSED)"
         self.log("Detected {} scarehobos ({} -> {}) {}"
                  .format(scareHobos, state['scareHoboParts'], 
                          self._scareHoboParts, guessText))
         self._scareHoboDamage += 8 * scareHobos
     self._initialized = True
     self._processLog(initData)
示例#6
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        if self.getCageState() in [UNKNOWN, EMPTY]:  # don't know cage status
            self._inCageFreedTime = None
        else:
            if self._updateInCageActions:
                self._updateInCageActions = False
                self._inCageHoboActions = self.getHoboActions(
                    self.inCage, events)
                self.log("{} action count = {}".format(
                    self.inCage, self._inCageHoboActions))

            # check if cage occupant has adventured in hobopolis
            currentHoboActions = self.getHoboActions(self.inCage, events)
            if currentHoboActions != self._inCageHoboActions:
                self.log("Detected {} escape: {} -> {}".format(
                    self.inCage, self._inCageHoboActions, currentHoboActions))
                self.chat("{} has left the C.H.U.M. cage.".format(self.inCage))
                self.setEscaped()

        # check sewer actions
        newTotalFreed = sum(
            f['turns'] for f in eventDbMatch(events, {'sewer_code': "rescue"}))
        if newTotalFreed > self._totalFreed and self.getCageState() == TRAPPED:
            self.setReleased(self.inCage)
        self._totalFreed = newTotalFreed
        self._totalSewerActions = sum(s['turns'] for s in events
                                      if s['category'] == "Sewers")
        return True
    def initialize(self, state, initData):
        events = initData['events']

        # see number of scarehobos killed
        self._killed = sum(
            k['turns'] for k in eventDbMatch(events, {'town_code': "combat"}))
        self._scareHoboDamage = state['damage']
        killDiff = self._killed - state['killed']

        # let's see if any scarehobos look like they were created
        # (indicated by a decrease in parts)
        self._guessState = state['scareHoboState']
        if killDiff > 50:
            # we missed some hobo activity, let's say the state is guessed
            # for good measure
            self._guessState = GUESSED
        self._scareHoboParts = self.getParts()
        if self._scareHoboParts is None:
            # usually, this only happens if we are in between instances
            self._scareHoboParts = state['scareHoboParts']
            self._guessState = GUESSED

        scareHobos = scareHobosCreated(state['scareHoboParts'],
                                       self._scareHoboParts)
        self._scareHoboDamage = state['damage']
        if scareHobos > 0:
            guessText = ""
            if self._guessState == GUESSED:
                guessText = " (changing state to GUESSED)"
            self.log("Detected {} scarehobos ({} -> {}) {}".format(
                scareHobos, state['scareHoboParts'], self._scareHoboParts,
                guessText))
            self._scareHoboDamage += 8 * scareHobos
        self._initialized = True
        self._processLog(initData)
    def _getNewEvents(self, events):
        t1 = time.time()

        newEvents = []

        # first, get a list of all db entries and players
        dbEntries = []
        players = set()
        for e in events:
            if e['db-match'] not in dbEntries:
                dbEntries.append(e['db-match'])
            players.add(e['userId'])

        # now, loop over all players and db entries
        for dbm in dbEntries:

            # skip unmatched events
            if not dbm:
                continue

            matchingDoneEvents = list(
                eventDbMatch(itertools.chain.from_iterable(self._snapshots),
                             dbm))
            matchingNewEvents = list(eventDbMatch(events, dbm))
            for uid in players:
                matchesUser = lambda x: x['userId'] == uid
                playerEvents = filter(matchesUser, matchingNewEvents)
                doneEvents = filter(matchesUser, matchingDoneEvents)
                playerTotalEvents = sum(pe['turns'] for pe in playerEvents)
                doneTotalEvents = sum(de['turns'] for de in doneEvents)
                eventDiff = playerTotalEvents - doneTotalEvents
                if eventDiff < 0:
                    self._log.warn("Snapshot: {}\nevents: {}".format(
                        self._snapshots, events))
                    raise RuntimeError("Error: detected {} events but "
                                       "{} in snapshot for user {} and "
                                       "db entry {}".format(
                                           playerTotalEvents, doneTotalEvents,
                                           uid, dbm))

                if eventDiff > 0:
                    newEvent = deepcopy(playerEvents[0])
                    newEvent['turns'] = eventDiff
                    newEvents.append(newEvent)
        self.debugLog("Built new DB entries in {} seconds".format(time.time() -
                                                                  t1))
        return newEvents
示例#9
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        # first: check number of dances available
        #        = 5 * flim-flams - dances so far
        # also see who has danced so far.
        self._watches = {
            w['userName']: w['turns']
            for w in eventDbMatch(events, {'ahbg_code': "watch"})
        }
        self._dances = {
            w['userName']: w['turns']
            for w in eventDbMatch(events, {'ahbg_code': "dance"})
        }

        self._availableDances = (
            5 * sum(f['turns']
                    for f in eventDbMatch(events, {'ahbg_code': "flimflam"})) -
            sum(f['turns']
                for f in eventDbMatch(events, {'ahbg_code': "dance"})) -
            sum(f['turns']
                for f in eventDbMatch(events, {'ahbg_code': "watch"})) -
            sum(f['turns']
                for f in eventDbMatch(events, {'ahbg_code': "fail"})))

        # any player in hobopolis is added to watch list
        for hoboplayer in set(item['userName'] for item in events
                              if 'userName' in item):
            if hoboplayer not in self._watches:
                self._watches[hoboplayer] = 0

        self._killed = (
            sum(k['turns'] for k in eventDbMatch(events, {
                'ahbg_code': "combat",
            })) -
            9 * sum(t['turns']
                    for t in eventDbMatch(events, {'ahbg_code': "tomb"})))

        self._ahbgDone = any(eventDbMatch(events, {'ahbg_code': "boss"}))

        if not self._open:
            if any(
                    eventDbMatch(
                        events,
                        {'category': "The Ancient Hobo Burial Ground"})):
                self._open = True
        return True
示例#10
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        #check hot hobos killed (negative for hot door opened)
        #  = defeated - 8 * hot doors opened
        self._hobosKilled = (
            sum(k['turns']
                for k in eventDbMatch(events, {'bb_code': "combat"})) -
            8 * sum(d['turns']
                    for d in eventDbMatch(events, {'bb_code': "door"})))

        # if Ol' Scratch is dead, set burnbarrel to finished
        self._bbDone = any(eventDbMatch(events, {'bb_code': "boss"}))

        if (self._hobosKilled > 0 or self._totalTires > 0
                or self._totalAvalanches > 0):
            self._open = True
        return True
示例#11
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        #check hot hobos killed (negative for hot door opened)
        #  = defeated - 8 * hot doors opened        
        self._hobosKilled = (
                      sum(k['turns'] for k in eventDbMatch(
                        events, {'bb_code': "combat"}))
                - 8 * sum(d['turns'] for d in eventDbMatch(
                        events, {'bb_code': "door"})))

        # if Ol' Scratch is dead, set burnbarrel to finished
        self._bbDone = any(eventDbMatch(events, {'bb_code': "boss"}))
                
        if (self._hobosKilled > 0 or 
                self._totalTires > 0 or 
                self._totalAvalanches > 0):
            self._open = True  
        return True
示例#12
0
    def initialize(self, state, initData):
        events = initData['events']
        self._db = initData['event-db']
        self._chatStrings = {
            d['sewer_code']: d['chat']
            for d in self._db if d['sewer_code']
        }

        self._totalFreed = sum(
            f['turns'] for f in eventDbMatch(events, {'sewer_code': "rescue"}))
        self._startupSewerActions = sum(s['turns'] for s in events
                                        if s['category'] == "Sewers")
        self.debugLog("Detected {} sewer actions at startup".format(
            self._startupSewerActions))

        self.inCage = state['inCage']
        self._inCageHoboActions = state['inCageHoboActions']
        self._inCageFreedTime = state['inCageFreedTime']

        if self.inCage is None:
            # previously unknown
            self.setUnknown()
        elif self.inCage == "":
            # nobody was in cage, but now we can't tell anymore.
            self.log("Restored from empty cage state, setting to unknown...")
            self.setUnknown()
        elif self._inCageFreedTime is not None:
            # somebody was previously in the cage, but freed
            if (self.getHoboActions(self.inCage, events) !=
                    self._inCageHoboActions):
                # they've adventured
                self.log("Player {} was freed and adventured in Hobopolis. "
                         "Setting to unknown...".format(self.inCage))
                self.setUnknown()
            else:
                # everything is the same!
                pass
        else:
            # somebody was in the cage but not freed
            if self._totalFreed != state['totalFreed']:
                # they have been freed!
                if (self.getHoboActions(self.inCage, events) !=
                        self._inCageHoboActions):
                    # and they've stayed put!
                    self.log("Player {} was freed and has not adventured "
                             "in Hobopolis. Setting to freed...".format(
                                 self.inCage))
                    self.setReleased(self.inCage)
                else:
                    # they've moved. we have no idea of cage state
                    self.log("Player {} was freed and adventured in Hobopolis."
                             " Setting to unknown...".format(self.inCage))
                    self.setUnknown()
            else:
                # everything is the same
                pass
示例#13
0
 def initialize(self, state, initData):
     events = initData['events']
     self._db = initData['event-db']
     self._chatStrings = {d['sewer_code']: d['chat'] for d in self._db
                          if d['sewer_code']}
     
     self._totalFreed = sum(
             f['turns'] for f in eventDbMatch(
                 events, {'sewer_code': "rescue"}))
     self._startupSewerActions = sum(
             s['turns'] for s in events if s['category'] == "Sewers")
     self.debugLog("Detected {} sewer actions at startup"
                   .format(self._startupSewerActions))
     
     self.inCage = state['inCage']
     self._inCageHoboActions = state['inCageHoboActions']
     self._inCageFreedTime = state['inCageFreedTime']
     
     if self.inCage is None:
         # previously unknown
         self.setUnknown()
     elif self.inCage == "":
         # nobody was in cage, but now we can't tell anymore.
         self.log("Restored from empty cage state, setting to unknown...")
         self.setUnknown()
     elif self._inCageFreedTime is not None:
         # somebody was previously in the cage, but freed
         if (self.getHoboActions(self.inCage, events) != 
                 self._inCageHoboActions):
             # they've adventured
             self.log("Player {} was freed and adventured in Hobopolis. "
                      "Setting to unknown...".format(self.inCage))
             self.setUnknown()
         else:
             # everything is the same!
             pass
     else:
         # somebody was in the cage but not freed
         if self._totalFreed != state['totalFreed']:
             # they have been freed!
             if (self.getHoboActions(self.inCage, events) != 
                     self._inCageHoboActions):
                 # and they've stayed put!
                 self.log("Player {} was freed and has not adventured "
                          "in Hobopolis. Setting to freed..."
                          .format(self.inCage))
                 self.setReleased(self.inCage)
             else:
                 # they've moved. we have no idea of cage state
                 self.log("Player {} was freed and adventured in Hobopolis."
                          " Setting to unknown...".format(self.inCage))
                 self.setUnknown()
         else:
             # everything is the same
             pass
示例#14
0
    def correctDamage(self, events, damage):
        """ adjust damage if any areas are open but we "think" they are not.
        make sure to do this AFTER accounting for scarehobos """

        minDamage = 0
        if any(eventDbMatch(events, {'town_code': "stage"})):
            minDamage = 1500 + 100 * max(0, self._stageClears - 1)
        elif any(eventDbMatch(events, {'pld_code': "combat"})):
            minDamage = 1250
        elif any(eventDbMatch(events, {'ahbg_code': "combat"})):
            minDamage = 1000
        elif any(eventDbMatch(events, {'heap_code': "combat"},
                                      {'heap_code': "trashcano"})):
            minDamage = 750
        elif any(eventDbMatch(events, {'ee_code': "combat"})):
            minDamage = 500
        elif any(eventDbMatch(events, {'bb_code': "combat"})):
            minDamage = 250
            
        if minDamage > damage:
            oldDC = self._damageCorrection
            self._damageCorrection += minDamage - damage
            self.log("Correcting damage: Detected {} damage, "
                     "minDamage = {}, old correction = {}, "
                     "new correction = {}"
                     .format(damage, minDamage, oldDC, self._damageCorrection))
            damage = self.getDoneAndState()[0]
        return damage
示例#15
0
 def _processLog(self, raidlog):
     events = raidlog['events']
     self._killed = sum(
         k['turns'] for k in eventDbMatch(events, {'town_code': "combat"}))
     if self._dungeonActive():
         newScareHoboParts = self.getParts()
         if newScareHoboParts is not None:
             if newScareHoboParts != self._scareHoboParts:
                 self.processPartChange(newScareHoboParts)
             self._scareHoboParts = newScareHoboParts
     else:
         self._scareHoboParts = [0] * 6
     return True
示例#16
0
 def _processLog(self, raidlog):
     events = raidlog['events']
     self._killed = sum(k['turns'] for k in eventDbMatch(
                            events, {'town_code': "combat"}))
     if self._dungeonActive():
         newScareHoboParts = self.getParts()
         if newScareHoboParts is not None:
             if newScareHoboParts != self._scareHoboParts:
                 self.processPartChange(newScareHoboParts)
             self._scareHoboParts = newScareHoboParts
     else:
         self._scareHoboParts = [0] * 6
     return True
示例#17
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        # first: check number of dances available 
        #        = 5 * flim-flams - dances so far
        # also see who has danced so far.
        self._watches = {w['userName']: w['turns']
                         for w in eventDbMatch(events, {'ahbg_code': "watch"})}
        self._dances = {w['userName']: w['turns']
                         for w in eventDbMatch(events, {'ahbg_code': "dance"})}

        self._availableDances = (
                5 * sum(f['turns'] for f in eventDbMatch(
                    events, {'ahbg_code': "flimflam"}))
                -   sum(f['turns'] for f in eventDbMatch(
                    events, {'ahbg_code': "dance"}))
                -   sum(f['turns'] for f in eventDbMatch(
                    events, {'ahbg_code': "watch"}))
                -   sum(f['turns'] for f in eventDbMatch(
                    events, {'ahbg_code': "fail"})))

        # any player in hobopolis is added to watch list             
        for hoboplayer in set(item['userName'] for item in events 
                              if 'userName' in item):
            if hoboplayer not in self._watches:
                self._watches[hoboplayer] = 0

        self._killed = (      
                  sum(k['turns'] for k in eventDbMatch(
                    events, {'ahbg_code': "combat",}))
            - 9 * sum(t['turns'] for t in eventDbMatch(
                    events, {'ahbg_code': "tomb"})))

        self._ahbgDone = any(eventDbMatch(events, {'ahbg_code': "boss"}))

        if not self._open:
            if any(eventDbMatch(events, {'category': 
                                         "The Ancient Hobo Burial Ground"})): 
                self._open = True
        return True
示例#18
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        
        # get dread status
        try:
            replies = self._raiseEvent("dread", "dread-overview", 
                                       data={'style': 'dict',
                                             'keys': ['status',
                                                      'index',
                                                      'locked']})
            self._dread = replies[0].data
        except IndexError:
            raise FatalError("DreadUniquesModule requires a "
                             "DreadOverviewModule with higher priority")

        newClaimed = defaultdict(list)
        userNames = {}
        for record in self._uniques:
            itemTxt = record['unique_text']
            quantity = toTypeOrNone(record['quantity'], int)
            if quantity is None:
                quantity = 1
            
            # see how many items were taken and who did it
            itemsAcquired = 0
            logMessage = ""
            for e in eventDbMatch(events, record):
                logMessage = e['event']
                newClaimed[itemTxt].extend([e['userId']] * e['turns'])
                userNames[e['userId']] = e['userName']
                itemsAcquired += e['turns']
            
            # compare to old list and announce if specified in the options
            if self._claimed is not None:
                # count up which users got this log message
                c1 = Counter(self._claimed.get(itemTxt, []))
                c2 = Counter(newClaimed.get(itemTxt, []))
                for k,v in c2.items():
                    # iterate through each user
                    numCollected = v - c1[k]
                    # print a pickup message for each time user X got item
                    # should be only once for dreadsylvania
                    for _ in range(numCollected):
                        self.chat("{} {} ({} remaining)."
                                  .format(userNames[k], 
                                          logMessage,
                                          quantity - itemsAcquired))
        self._claimed = newClaimed
        return True
示例#19
0
 def _doProcessLog(self, raidlog, suppressChat=False):
     events = raidlog['events']
     doneAmt = self.getDoneAndState()[0] 
     doneAmt = self.correctDamage(events, doneAmt)
     self._killed = sum(k['turns'] for k in eventDbMatch(
                            events, {'town_code': "combat"}))
     newPerformers = stageCount(events)
     newStageClears = stageClearCount(events)
     if newStageClears > self._stageClears:
         self._tentOpen = KNOWN_CLOSED
         if not suppressChat:
             self.chat("{} The tent will open when 100 more hobos "
                       "are killed.".format(self.getTag()))
         self._lastTent = self.getDoneAndState()[0]
     elif newPerformers > self._totalperformers:
         self._tentOpen = KNOWN_OPEN
     self._totalperformers = newPerformers
     self._stageClears = newStageClears
     self.checkOpenings(doneAmt, suppressChat)
     return True
示例#20
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        # hobos killed by non-yodels
        oldYodel = self._yodel
        oldPipes = self._pipes

        self._killed = sum(
            coldhobo['turns']
            for coldhobo in eventDbMatch(events, {'ee_code': "combat"}))

        self._yodel = ([
            sum(yodel0['turns']
                for yodel0 in eventDbMatch(events, {'ee_code': "yodel0"})),
            sum(yodel1['turns']
                for yodel1 in eventDbMatch(events, {'ee_code': "yodel1"})),
            sum(yodel2['turns']
                for yodel2 in eventDbMatch(events, {'ee_code': "yodel2"}))
        ])

        self._pipes = sum(
            pipeevent['turns']
            for pipeevent in eventDbMatch(events, {'ee_code': "pipe3"}))

        self._exposureDone = any(eventDbMatch(events, {'ee_code': "boss"}))

        if self._killed > 0 or self._pipes > 0 or sum(self._yodel) > 0:
            self._open = True

        if oldPipes < self._pipes and oldPipes is not None:
            #self.log("Added {} pipes".format(self._pipes - oldPipes))
            pass

        if oldYodel is not None:
            yodelDiff = [new - old for new, old in zip(self._yodel, oldYodel)]
            for _idx, diff in enumerate(yodelDiff):
                if diff > 0:
                    #self.log("Added {} yodel{}".format(diff,_idx), 'exposure')
                    pass
        return True
示例#21
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        # hobos killed by non-yodels
        oldYodel = self._yodel
        oldPipes = self._pipes
        
        self._killed = sum(
                coldhobo['turns'] for coldhobo in eventDbMatch(
                    events, {'ee_code': "combat"}))
            
        self._yodel = (
                [sum(yodel0['turns'] for yodel0 in eventDbMatch(
                    events, {'ee_code': "yodel0"})),
                 sum(yodel1['turns'] for yodel1 in eventDbMatch(
                    events, {'ee_code': "yodel1"})),
                 sum(yodel2['turns'] for yodel2 in eventDbMatch(
                    events, {'ee_code': "yodel2"}))])

        self._pipes = sum(pipeevent['turns'] for pipeevent in eventDbMatch(
                              events, {'ee_code': "pipe3"}))

        self._exposureDone = any(eventDbMatch(events, {'ee_code': "boss"}))

        if self._killed > 0 or self._pipes > 0 or sum(self._yodel) > 0:
            self._open = True
            
        if oldPipes < self._pipes and oldPipes is not None:
            #self.log("Added {} pipes".format(self._pipes - oldPipes))
            pass
           
        if oldYodel is not None: 
            yodelDiff = [new-old for new,old in zip(self._yodel, oldYodel)]
            for _idx,diff in enumerate(yodelDiff):
                if diff > 0:
                    #self.log("Added {} yodel{}".format(diff,_idx), 'exposure')
                    pass
        return True
示例#22
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        # check stench hobos killed
        self._killed = (
            sum(stenchhobo['turns'] for stenchhobo in eventDbMatch(
                events, {'heap_code': "combat"})) + 5 *
            sum(trash['turns']
                for trash in eventDbMatch(events, {'heap_code': "trashcano"})))

        self._totalStench = (
            4 +
            sum(t['turns']
                for t in eventDbMatch(events, {'heap_code': "trashcano"})) +
            sum(t['turns']
                for t in eventDbMatch(events, {'heap_code': "stench"})) -
            sum(f['turns']
                for f in eventDbMatch(events, {'heap_code': "unstench"})))

        # if Oscus is dead, set the heap to finished
        self._heapDone = any(eventDbMatch(events, {'heap_code': "boss"}))

        if self._killed > 0:
            self._open = True
        return True
示例#23
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        # check stench hobos killed
        self._unpopularity = (  
                sum(u['turns'] for u in eventDbMatch(
                        events, {'pld_code': "unpopular"}))
                - sum(p['turns'] for p in eventDbMatch(
                        events, {'pld_code': "popular"})))
        
        self._pldKilled = (      
                sum(k['turns'] for k in eventDbMatch(
                                    events, {'pld_code': "combat"}))
                - 6 * sum(d['turns'] for d in eventDbMatch(
                                    events, {'pld_code': "dumpster"})))

        self._pldFights = sum(f['turns'] for f in eventDbMatch(
                                  events, {'pld_code': "barfight"}))
            
        # if Chester is dead, set the heap to finished
        if self._pldKilled > 0 or self._pldFights > 0:
            self._open = True
        
        self._pldDone = any(eventDbMatch(events, {'pld_code': "boss"}))
        return True
示例#24
0
    def _eventTimeline(self, events, nameShorthands):
        timeline = []
        timelineKills = [0, 0, 0]
        newEvents = self._getNewEvents(events)
        t1 = time.time()
        snapshots = deepcopy(self._snapshots)
        snapshots.append(newEvents)
        for snapshot in snapshots:
            timelineText = []
            for area in range(3):
                txtList = []
                areaName = _areas[area]

                # first, let's find kills
                kills = defaultdict(int)
                killEvents = eventDbMatch(snapshot, {
                    'category': areaName,
                    'zone': "(combat)",
                    'subzone': "normal"
                })
                for e in killEvents:
                    timelineKills[area] += e['turns']
                    kills[e['userId']] += e['turns']
                for uid, k in kills.items():
                    txtList.append(" {}: {} kills".format(
                        nameShorthands[uid], k))

                bossEvents = eventDbMatch(snapshot, {
                    'category': areaName,
                    'zone': "(combat)",
                    'subzone': "boss"
                }, {
                    'category': areaName,
                    'zone': "(combat)",
                    'subzone': "boss_defeat"
                })
                for e in bossEvents:
                    txtList.append("*{} {}".format(nameShorthands[e['userId']],
                                                   e['event']))

                allEvents = eventDbMatch(snapshot, {'category': areaName})
                for e in allEvents:
                    dbm = e['db-match']
                    if dbm.get('zone') == "(combat)":
                        continue
                    if dbm.get('unique_text', "").strip() != "":
                        txtList.append("*{} got {} at {}".format(
                            nameShorthands[e['userId']], dbm['code'],
                            dbm['zone']))
                    elif dbm.get('zone') == "(unlock)":
                        txtList.append("-{} unlocked {}".format(
                            nameShorthands[e['userId']], dbm['subzone']))
                    else:
                        txtList.append("-{} did {} at {}".format(
                            nameShorthands[e['userId']], dbm['code'],
                            dbm['zone']))
                txtList.sort()
                timelineText.append(txtList)
            timeline.append({
                'kills': deepcopy(timelineKills),
                'text': timelineText
            })
        self.debugLog("Built timeline in {} seconds".format(time.time() - t1))
        return timeline
示例#25
0
def buskCount(events):
    return sum(b['turns'] for b in eventDbMatch(events, {'town_code': "busk"}))
示例#26
0
def moshCount(events):
    return sum(m['turns'] for m in eventDbMatch(events, {'town_code': "mosh"}))
示例#27
0
def uniqueStagePlayers(events):
    players = set(s['userId']
                  for s in eventDbMatch(events, {'town_code': "stage"}))
    return len(players)
示例#28
0
def stageCount(events):
    return sum(s['turns']
               for s in eventDbMatch(events, {'town_code': "stage"}))
示例#29
0
def ruinCount(events):
    return sum(r['turns'] for r in eventDbMatch(events, {'town_code': "ruin"}))
示例#30
0
def ruinCount(events):
    return sum(r['turns'] for r in eventDbMatch(
                               events, {'town_code': "ruin"}))
示例#31
0
def uniqueStagePlayers(events):
    players = set(s['userId'] for s in eventDbMatch(
                               events, {'town_code': "stage"}))
    return len(players)
示例#32
0
def moshCount(events):
    return sum(m['turns'] for m in eventDbMatch(
                               events, {'town_code': "mosh"}))
示例#33
0
def buskCount(events):
    return sum(b['turns'] for b in eventDbMatch(
                               events, {'town_code': "busk"}))
示例#34
0
def stageCount(events):
    return sum(s['turns'] 
               for s in eventDbMatch(events, {'town_code': "stage"}))
示例#35
0
    def initialize(self, state, initData):
        events = initData['events']
        self._db = initData['event-db']
        
        self._killed = sum(k['turns'] for k in eventDbMatch(
                               events, {'town_code': "combat"}))
        self._stageClears = stageClearCount(events)
        self._totalperformers = stageCount(events)
        self._damageCorrection = state['damageCorrection']
        
        # do an initial damage calculation
        (doneAmt, guessState) = self.getDoneAndState() 
        doneAmt = self.correctDamage(events, doneAmt)
        
        self._doProcessLog(initData, suppressChat=True)
        
        self._lastOpening = self.getDoneAndState()[0]
        self.log("Last opening: {}".format(self._lastOpening))

        # figure out the whole tent opening thing
        lastStageClears = state['stageClears']
        lastPerformers = state['totalPerformers']
        onStage = self.getOnStage()[0]
        killDiff = doneAmt - state['lastTent']
        if onStage > 0:
            # we KNOW that the stage is open
            self._tentOpen = KNOWN_OPEN            
            self._lastTent = doneAmt - 100
            self.log("Detected {} or more players on stage -> OPEN"
                     .format(onStage))
        elif guessState == KNOWN and doneAmt < 1500:
            # we know it's not open
            self._tentOpen = KNOWN_UNOPENED
            self._lastTent = 0
        elif doneAmt < 1250:
            # there have been no adventures in the PLD and we are fairly 
            # certain the tent is not open yet.
            self._tentOpen = KNOWN_UNOPENED
            self._lastTent = 0            
        elif killDiff < 100:
            # we know that the stage still not reopened
            self._tentOpen = KNOWN_CLOSED
            self._lastTent = state['lastTent']
        elif lastStageClears == self._stageClears:
            # unfortunately, busking with 0 players on stage is not logged, 
            # so there's a chance that the stage is closed now.
            self._tentOpen = UNKNOWN
            self._lastTent = doneAmt
        elif lastPerformers == self._totalperformers:
            # the stage has been cleared, no new performers. But we don't
            # know when :/
            self._tentOpen = UNKNOWN
            self._lastTent = doneAmt
        else:
            # stage is cleared, but there may be new performers
            self._tentOpen = UNKNOWN
            self._lastTent = doneAmt

        for numKills, areaName, procName, _tagName in self.openings:
            if doneAmt > numKills:
                self._raiseEvent("open", procName)
                self.log("Opening {}".format(areaName))
示例#36
0
    def _processLog(self, raidlog):
        events = raidlog['events']
        self._done = [any(eventDbMatch(events, 
                                       {'category': self._areas[i], 
                                        'zone': "(combat)",
                                        'subzone': "boss"}))
                      for i in range(3)]
        self._drunk = raidlog['dread']['drunkenness']
        
        newKilled = [raidlog['dread'].get('forest', 0),
                     raidlog['dread'].get('village', 0),
                     raidlog['dread'].get('castle', 0)]
        areaNames = ["Woods are", "Village is", "Castle is"]
        if self._killed is not None:
            for old,new,area in zip(self._killed, newKilled, areaNames):
                for threshold in self._notifyPercent:
                    if old < 10*threshold <= new:
                        self.chat("The {} {}% complete.".format(area,
                                                                int(new/10)))
                        break
        self._killed = newKilled

        oldKills = self._kills
        oldDefeats = self._defeats
        oldBanished = self._banished
        self._banished = {} 
        self._kills = {}      
        self._defeats = {}  
        prefix = r'defeated\s+(?:hot|cold|spooky|stench|sleaze)\s+'
        prefixDef = r'was defeated by\s+(?:hot|cold|spooky|stench|sleaze)\s+'
        for monster in self._monsters:
            self._kills[monster] = (
                sum(e['turns'] for e in eventFilter(events, 
                                                    prefix + monster)))
            self._defeats[monster] = (
                sum(e['turns'] for e in eventFilter(events, 
                                                    prefixDef + monster)))
            self._banished[monster] = (
                sum(e['turns'] for e in eventFilter(events,
                            "drove some " + self._plurals[monster])))
            
        # do likelihood ratio test to determine which monsters are more
        # populous
        self._doLRT(oldBanished, oldKills, oldDefeats)
                        
        self._balance = {i: (self._kills[self._monsters[2*i]]
                             - self._kills[self._monsters[2*i+1]])
                         for i in range(3)}
        
        self._level = [1 + sum(e['turns'] 
                               for e in eventFilter(events, 
                                                    "made the " + a + " less"))
                       for a in ["forest", "village", "castle"]]
        
        self._kisses = raidlog['dread'].get('kisses', 0)
        
        self._locked = []
        for area in self._lockedAreas:
            if not any(eventDbMatch(events, area)):
                self._locked.append(area)
        return True
示例#37
0
def stageClearCount(events):
    return sum(c['turns'] for c in eventDbMatch(
                   events, 
                   {'town_code': "ruin"}, 
                   {'town_code': "busk"}, 
                   {'town_code': "mosh"}))