def __init__(self, char_id): self.char_id = char_id try: self.achievement = MongoAchievement.objects.get(id=char_id) except DoesNotExist: self.achievement = MongoAchievement(id=char_id) self.achievement.doing = {} self.achievement.display = ACHIEVEMENT_FIRST_IDS self.achievement.finished = [] self.achievement.complete = [] self.achievement.save()
class Achievement(object): def __init__(self, char_id): self.char_id = char_id try: self.achievement = MongoAchievement.objects.get(id=char_id) except DoesNotExist: self.achievement = MongoAchievement(id=char_id) self.achievement.doing = {} self.achievement.display = ACHIEVEMENT_FIRST_IDS self.achievement.finished = [] self.achievement.complete = [] self.achievement.save() self.check() def check(self): if not self.achievement.finished: attachment = Attachment(self.char_id) if 4 in attachment.attachment.prize_ids: attachment.attachment.prize_ids.remove(4) attachment.attachment.save() def has_prizes(self): # 是否有可领取奖励 if not self.achievement.finished: return False for i in self.achievement.finished: if i in self.achievement.display: return True return False def trig(self, condition_id, new_value, send_notify=True): achs = ACHIEVEMENT_CONDITIONS[condition_id] for a in achs: self.trig_achievement(a, new_value, send_notify=send_notify) def trig_achievement(self, ach, new_value, send_notify=True): achievement_id = ach.id if achievement_id in self.achievement.complete or achievement_id in self.achievement.finished: return attachment = Attachment(self.char_id) str_id = str(achievement_id) decoded_condition_value = ach.decoded_condition_value def finish_it(): if achievement_id not in self.achievement.finished: self.achievement.finished.append(achievement_id) if str_id in self.achievement.doing: self.achievement.doing.pop(str_id) if achievement_id in self.achievement.display: attachment.save_to_prize(4) if ach.mode == 1: # 多个ID条件 actual_new_value = [i for i in new_value if i in decoded_condition_value] if not actual_new_value: return if str_id in self.achievement.doing: values = [int(i) for i in self.achievement.doing[str_id].split(',')] else: values = [] for av in actual_new_value: if av not in values: values.append(av) if set(values) == set(decoded_condition_value): # FINISH finish_it() else: self.achievement.doing[str_id] = ','.join([str(i) for i in values]) elif ach.mode == 2: # 单个ID条件 if new_value != decoded_condition_value: return # FINISH finish_it() elif ach.mode == 3: # 普通数量条件 数量累加 if str_id in self.achievement.doing: value = self.achievement.doing[str_id] else: value = 0 value += new_value if value >= decoded_condition_value: # FINISH finish_it() else: self.achievement.doing[str_id] = value elif ach.mode == 4: # 阀值数量条件 # 这里不叠加,只是简单的比较 if new_value >= decoded_condition_value: # FINISH finish_it() else: self.achievement.doing[str_id] = new_value else: # 反向阀值条件, 比较小于就完成 if new_value <= decoded_condition_value: # FINISH finish_it() else: self.achievement.doing[str_id] = new_value self.achievement.save() if send_notify and achievement_id in self.achievement.display: msg = UpdateAchievementNotify() self._fill_up_achievement_msg(msg.achievement, ach) publish_to_char(self.char_id, pack_msg(msg)) def get_reward(self, achievement_id): try: ach = ACHIEVEMENTS[achievement_id] except KeyError: raise SanguoException( errormsg.ACHIEVEMENT_NOT_EXIST, self.char_id, "Achievement Get Reward", "{0} not exist".format(achievement_id) ) if achievement_id not in self.achievement.display: raise SanguoException( errormsg.ACHIEVEMENT_NOT_FINISH, self.char_id, "Achievement Get Reward", "{0} not in display".format(achievement_id) ) if achievement_id not in self.achievement.finished: raise SanguoException( errormsg.ACHIEVEMENT_NOT_FINISH, self.char_id, "Achievement Get Reward", "{0} not finished".format(achievement_id) ) self.achievement.finished.remove(achievement_id) self.achievement.complete.append(achievement_id) updated_achs = [ach] if ach.next: index = self.achievement.display.index(achievement_id) self.achievement.display[index] = ach.next updated_achs.append(ACHIEVEMENTS[ach.next]) if ach.next in self.achievement.finished: attachment = Attachment(self.char_id) attachment.save_to_prize(4) self.achievement.save() for up_ach in updated_achs: msg = UpdateAchievementNotify() self._fill_up_achievement_msg(msg.achievement, up_ach) publish_to_char(self.char_id, pack_msg(msg)) standard_drop = self.send_reward(achievement_id, ach.sycee, ach.package) return standard_drop_to_attachment_protomsg(standard_drop) def send_reward(self, aid, sycee, packages): if not sycee and not packages: return make_standard_drop_from_template() if packages: ps = [int(i) for i in packages.split(',')] else: ps = [] drops = get_drop(ps) drops['sycee'] += sycee if sycee else 0 resource = Resource(self.char_id, "Achievement Reward", "achievement {0}".format(aid)) drops = resource.add(**drops) return drops def send_notify(self): msg = AchievementNotify() for v in ACHIEVEMENTS.values(): a = msg.achievements.add() self._fill_up_achievement_msg(a, v) publish_to_char(self.char_id, pack_msg(msg)) def _fill_up_achievement_msg(self, msg, ach): msg.id = ach.id if ach.id in self.achievement.finished and ach.id in self.achievement.display: status = MsgAchievement.REWARD elif ach.id in self.achievement.complete: status = MsgAchievement.COMPLETE else: status = MsgAchievement.DOING msg.status = status msg.show = ach.id in self.achievement.display decoded_condition_value = ach.decoded_condition_value if ach.mode == 1: msg.mach.condition.extend(decoded_condition_value) if msg.status == MsgAchievement.DOING: if str(ach.id) in self.achievement.doing: msg.mach.current.extend([int(i) for i in self.achievement.doing[str(ach.id)].split(',')]) else: msg.mach.current.extend(decoded_condition_value) elif ach.mode == 2: msg.sach.condition = decoded_condition_value else: msg.cach.condition = decoded_condition_value if msg.status == MsgAchievement.DOING: if str(ach.id) in self.achievement.doing: msg.cach.current = int(self.achievement.doing[str(ach.id)]) else: msg.cach.current = 0 else: msg.cach.current = decoded_condition_value
class Achievement(object): def __init__(self, char_id): self.char_id = char_id try: self.achievement = MongoAchievement.objects.get(id=char_id) except DoesNotExist: self.achievement = MongoAchievement(id=char_id) self.achievement.doing = {} self.achievement.display = ACHIEVEMENT_FIRST_IDS self.achievement.finished = [] self.achievement.complete = [] self.achievement.save() def trig(self, condition_id, new_value, send_notify=True): achs = ACHIEVEMENT_CONDITIONS[condition_id] for a in achs: self.trig_achievement(a, new_value, send_notify=send_notify) def trig_achievement(self, ach, new_value, send_notify=True): achievement_id = ach.id if achievement_id in self.achievement.complete or achievement_id in self.achievement.finished: return attachment = Attachment(self.char_id) str_id = str(achievement_id) decoded_condition_value = ach.decoded_condition_value def finish_it(): if achievement_id not in self.achievement.finished: self.achievement.finished.append(achievement_id) if str_id in self.achievement.doing: self.achievement.doing.pop(str_id) if achievement_id in self.achievement.display: attachment.save_to_prize(4) if ach.mode == 1: # 多个ID条件 actual_new_value = [ i for i in new_value if i in decoded_condition_value ] if not actual_new_value: return if str_id in self.achievement.doing: values = [ int(i) for i in self.achievement.doing[str_id].split(',') ] else: values = [] for av in actual_new_value: if av not in values: values.append(av) if set(values) == set(decoded_condition_value): # FINISH finish_it() else: self.achievement.doing[str_id] = ','.join( [str(i) for i in values]) elif ach.mode == 2: # 单个ID条件 if new_value != decoded_condition_value: return # FINISH finish_it() elif ach.mode == 3: # 普通数量条件 数量累加 if str_id in self.achievement.doing: value = self.achievement.doing[str_id] else: value = 0 value += new_value if value >= decoded_condition_value: # FINISH finish_it() else: self.achievement.doing[str_id] = value elif ach.mode == 4: # 阀值数量条件 # 这里不叠加,只是简单的比较 if new_value >= decoded_condition_value: # FINISH finish_it() else: self.achievement.doing[str_id] = new_value else: # 反向阀值条件, 比较小于就完成 if new_value <= decoded_condition_value: # FINISH finish_it() else: self.achievement.doing[str_id] = new_value self.achievement.save() if send_notify and achievement_id in self.achievement.display: msg = UpdateAchievementNotify() self._fill_up_achievement_msg(msg.achievement, ach) publish_to_char(self.char_id, pack_msg(msg)) def get_reward(self, achievement_id): try: ach = ACHIEVEMENTS[achievement_id] except KeyError: raise SanguoException(errormsg.ACHIEVEMENT_NOT_EXIST, self.char_id, "Achievement Get Reward", "{0} not exist".format(achievement_id)) if achievement_id not in self.achievement.display: raise SanguoException(errormsg.ACHIEVEMENT_NOT_FINISH, self.char_id, "Achievement Get Reward", "{0} not in display".format(achievement_id)) if achievement_id not in self.achievement.finished: raise SanguoException(errormsg.ACHIEVEMENT_NOT_FINISH, self.char_id, "Achievement Get Reward", "{0} not finished".format(achievement_id)) self.achievement.finished.remove(achievement_id) self.achievement.complete.append(achievement_id) updated_achs = [ach] if ach.next: index = self.achievement.display.index(achievement_id) self.achievement.display[index] = ach.next updated_achs.append(ACHIEVEMENTS[ach.next]) if ach.next in self.achievement.finished: attachment = Attachment(self.char_id) attachment.save_to_prize(4) self.achievement.save() for up_ach in updated_achs: msg = UpdateAchievementNotify() self._fill_up_achievement_msg(msg.achievement, up_ach) publish_to_char(self.char_id, pack_msg(msg)) standard_drop = self.send_reward(achievement_id, ach.sycee, ach.package) return standard_drop_to_attachment_protomsg(standard_drop) def send_reward(self, aid, sycee, packages): if not sycee and not packages: return make_standard_drop_from_template() if packages: ps = [int(i) for i in packages.split(',')] else: ps = [] drops = get_drop(ps) drops['sycee'] += sycee if sycee else 0 resource = Resource(self.char_id, "Achievement Reward", "achievement {0}".format(aid)) drops = resource.add(**drops) return drops def send_notify(self): msg = AchievementNotify() for v in ACHIEVEMENTS.values(): a = msg.achievements.add() self._fill_up_achievement_msg(a, v) publish_to_char(self.char_id, pack_msg(msg)) def _fill_up_achievement_msg(self, msg, ach): msg.id = ach.id if ach.id in self.achievement.finished and ach.id in self.achievement.display: status = MsgAchievement.REWARD elif ach.id in self.achievement.complete: status = MsgAchievement.COMPLETE else: status = MsgAchievement.DOING msg.status = status msg.show = ach.id in self.achievement.display decoded_condition_value = ach.decoded_condition_value if ach.mode == 1: msg.mach.condition.extend(decoded_condition_value) if msg.status == MsgAchievement.DOING: if str(ach.id) in self.achievement.doing: msg.mach.current.extend([ int(i) for i in self.achievement.doing[str(ach.id)].split(',') ]) else: msg.mach.current.extend(decoded_condition_value) elif ach.mode == 2: msg.sach.condition = decoded_condition_value else: msg.cach.condition = decoded_condition_value if msg.status == MsgAchievement.DOING: if str(ach.id) in self.achievement.doing: msg.cach.current = int(self.achievement.doing[str(ach.id)]) else: msg.cach.current = 0 else: msg.cach.current = decoded_condition_value