def requestEffect(self):
        if not self.air.newsManager.isHolidayRunning(self.holiday):
            return

        avId = self.air.getAvatarIdFromSender()
        av = self.air.doId2do.get(avId)

        if not av:
            return

        holidayInfo = HolidayGlobals.getHoliday(self.holiday)
        expireTime = int(
            HolidayGlobals.getServerTime(HolidayGlobals.getEndDate(holidayInfo) + datetime.timedelta(days=1)) / 60
        )

        if "scavengerHunt" in holidayInfo:
            scavengerHunt = av.getScavengerHunt()

            if self.zoneId in scavengerHunt:
                self.sendUpdateToAvatarId(avId, "effectDone", [0])
            else:
                scavengerHunt.append(self.zoneId)
                av.b_setScavengerHunt(scavengerHunt)
                av.addMoney(HolidayGlobals.CAROLING_REWARD)
                self.sendUpdateToAvatarId(avId, "effectDone", [HolidayGlobals.CAROLING_REWARD])

            if len(scavengerHunt) == HolidayGlobals.SCAVENGER_HUNT_LOCATIONS:
                av.b_setCheesyEffect(self.effectId, 0, expireTime)
        else:
            av.b_setCheesyEffect(self.effectId, 0, expireTime)
            self.sendUpdateToAvatarId(avId, "effectDone", [0])
    def endHoliday(self, id):
        if id not in self.activeHolidays or id not in HolidayGlobals.Holidays:
            return

        holiday = HolidayGlobals.getHoliday(id)

        self.activeHolidays.remove(id)
        self.broadcastHoliday(holiday, 'endMessage')
        self.endSpecialHoliday(id)
    def startHoliday(self, id, ongoing=False):
        if id in self.activeHolidays or id not in HolidayGlobals.Holidays:
            return

        holiday = HolidayGlobals.getHoliday(id)

        self.activeHolidays.append(id)
        self.broadcastHoliday(holiday, 'ongoingMessage' if ongoing else 'startMessage')
        self.startSpecialHoliday(id)
    def effectDone(self, amount):
        holidayInfo = HolidayGlobals.getHoliday(self.holiday)

        self.cr.newsManager.broadcastHoliday(holidayInfo, 'effectMessage')

        if 'scavengerHunt' in holidayInfo:
            type = holidayInfo['scavengerHunt']

            if type == HolidayGlobals.TRICK_OR_TREAT:
                base.localAvatar.trickOrTreatTargetMet(amount)
            elif type == HolidayGlobals.WINTER_CAROLING:
                base.localAvatar.winterCarolingTargetMet(amount)
    def __saidPhrase(self, phraseId):
        if not self.cr.newsManager.isHolidayRunning(self.holiday):
            return

        currentTime = time.time()

        if self.nextTime > currentTime:
            return

        holidayInfo = HolidayGlobals.getHoliday(self.holiday)

        if 'speedchatIndexes' not in holidayInfo or phraseId not in holidayInfo['speedchatIndexes']:
            return

        if 'effectDelay' in holidayInfo:
            self.nextTime = currentTime + holidayInfo['effectDelay']

        self.sendUpdate('requestEffect')
 def isHolidayInRange(self, holiday, date):
     if 'weekDay' in holiday:
         return holiday['weekDay'] == date.weekday()
     else:
         return HolidayGlobals.getStartDate(holiday) <= date <= HolidayGlobals.getEndDate(holiday)