Esempio n. 1
0
 def do_item(self):
     """
     战场上的使用物品行为
     """
     self.battle.sequence.append({
         "current": self.battle.current,
         "action": self,
         "results": {}
     })
     self.battle.status_work(BattlePhase.BeforeItem)
     should_hit = common.if_rate(self.subject.hit_rate)
     if not should_hit:
         self.battle.add_event(self.subject, BattleEvent.ACTFault)
     for q in self.objects:
         if self.battle.is_friend(self.subject, q):
             continue
         if self.subject.hit_rate > 1:
             should_dodge = common.if_rate(1 - (1 - q.dodge_rate) *
                                           self.subject.hit_rate)
         else:
             should_dodge = common.if_rate(q.dodge_rate)
         # 失误与闪避在结果上不做区分,必要时可以通过是否有ACTFault来判断
         if not should_hit or should_dodge:
             self.battle.add_event(q, BattleEvent.ACTMissed)
     self.item.work(self.subject, battle=self.battle)
     self.battle.redirect(self.subject, self.objects, self.target,
                          self.item)
     for q in self.battle.alive:
         q.correct()
         q.hp += q.hp_delta
         q.mp += q.mp_delta
         self.battle.add_event(q, BattleEvent.HPChanged, value=q.hp_delta)
         self.battle.add_event(q, BattleEvent.MPChanged, value=q.mp_delta)
     self.battle.status_work(BattlePhase.AfterItem)
Esempio n. 2
0
 def damage(self, skill, p, q):
     should_critical = common.if_rate(p.critical_rate)
     should_anti_damage = common.if_rate(q.anti_damage_rate)
     if skill.power == 0:
         return 0, 0, should_critical, False
     mp_rate = 1 if skill.mp == 0 else max(1, -1 * p.mp_delta / skill.mp)
     real_attack = p.attack
     real_defense = q.defense
     #vp = getattr(p, skill.style.lower())
     #vq = getattr(q, skill.style.lower())
     vp, vq = self.calculate_weapon(skill, p, q)
     #real_attack += (skill.power + 250) * math.pow(1.005, vp) * math.pow(1.002, p.neigong)
     attack_dire = self.map.direction(self.map.location(p),
                                      self.map.location(q))
     if attack_dire == q.direction:
         dire_ratio = 1.5
     elif attack_dire == (q.direction +
                          1) % 6 or attack_dire == (q.direction + 5) % 6:
         dire_ratio = 1.2
     else:
         dire_ratio = 1
     act_neigong_p = int(p.neigong * (p.mp_limit / p.mp_max))
     act_neigong_q = int(q.neigong * (q.mp_limit / q.mp_max))
     real_attack += skill.power * mp_rate * math.pow(1.005, vp) * math.pow(
         1.002, act_neigong_p) * p.yinyang_rate(skill.yinyang)
     #real_attack_base = real_attack
     #real_attack_skill = int(skill.power * math.pow(1.005, vp) * math.pow(1.002, p.neigong) * p.yinyang_rate(skill.yinyang))
     #real_attack = int(math.sqrt(real_attack_base * real_attack_skill) * mp_rate)
     real_defense *= math.pow(1.005, vq) * math.pow(
         1.002, act_neigong_q) * max(1, q.yinyang_rate(skill.yinyang))
     real_attack -= max(p.hunger - 500, 0)
     real_attack = int(real_attack * 0.6)
     real_defense = int(real_defense * 0.6)
     #real_attack = int(real_attack * 1.4)
     #real_defense = int(real_defense / 1.4)
     #print(p.name, q.name, real_attack, real_defense)
     hp_damaged = common.random_gap(real_attack, 0.025) - common.random_gap(
         real_defense, 0.025)
     mp_damaged = 0
     if hp_damaged <= 0:
         hp_damaged = 1
     hp_damaged *= dire_ratio
     #should_critical = common.if_rate(p.critical_rate)
     #should_anti_damage = common.if_rate(q.anti_damage_rate)
     if should_critical:
         #hp_damaged = hp_damaged * p.critical_damage
         hp_damaged = hp_damaged * 1.8
     if should_anti_damage:
         #hp_damaged = max(1, hp_damaged * 0.5)
         hp_damaged = max(1, hp_damaged * q.anti_damage)
     return int(hp_damaged), int(
         mp_damaged), should_critical, should_anti_damage
Esempio n. 3
0
 def work(self, subject, objects=[], **kwargs):
     battle = kwargs["battle"]
     if subject != battle.sequence[-1]["action"].subject:
         return
     for obj in battle.sequence[-1]["action"].objects:
         if len(obj.items) == 0:
             self.battle.add_event(q, BattleEvent.ACTMissed)
             continue
         itm = random.sample(obj.items, 1)[0]
         if itm.tpl_id == "ITEM_MONEY":
             quantity = random.randint(1, obj.quantities[itm.tpl_id])
         else:
             quantity = 1
         effe_ratio = self.base_rate * self.factor(subject) * math.pow(
             2, -1 * itm.rank)
         if common.if_rate(effe_ratio):
             obj.minus_item(itm, quantity)
             subject.add_item(itm, quantity)
             MSG(style=MSG.Effect,
                 subject=subject,
                 effect=self,
                 details={
                     "object": obj.name,
                     "item": itm.name,
                     "item_rank": itm.rank,
                     "quantity": quantity
                 })
         else:
             self.battle.add_event(q, BattleEvent.ACTMissed)
Esempio n. 4
0
 def work(self, subject, objects=[], **kwargs):
     battle = kwargs["battle"]
     if subject not in battle.sequence[-1]["action"].objects:
         return
     if battle.event(subject, BattleEvent.ACTMissed) is not None:
         return
     if common.if_rate(0.5):
         mp_damage = max(subject.hp_delta,
                         -1 * (subject.mp + subject.mp_delta))
         subject.mp_delta += mp_damage
         subject.hp_delta -= mp_damage
         subject.wound -= int(mp_damage * 0.5)
         #subject.correct()
         if not battle.silent:
             MSG(style=MSG.Effect, subject=subject, effect=self)
Esempio n. 5
0
 def work(self, subject, objects=[], **kwargs):
     battle = kwargs["battle"]
     if subject == battle.sequence[-1]["action"].subject:
         return
     if battle.is_friend(subject, battle.sequence[-1]["action"].subject):
         return
     if subject not in battle.sequence[-1]["action"].objects:
         return
     if battle.event(subject, BattleEvent.ACTMissed) is not None:
         return
     effe_factor = self.factor(subject)
     effe_ratio = 0.2 * effe_factor
     if subject.hp_delta < 0 and common.if_rate(effe_ratio):
         subject.hp_delta = -1
         if not battle.silent:
             MSG(style=MSG.Effect, subject=subject, effect=self)
Esempio n. 6
0
 def work(self, subject, objects=[], **kwargs):
     battle = kwargs["battle"]
     if subject != battle.sequence[-1]["action"].subject:
         return
     turbotime = battle.sequence[-1]["action"].turbotime
     if turbotime is None:
         turbotime = 1
     if self.maxcount is not None and turbotime >= self.maxcount:
         return
     effe_ratio = self.factor(subject) * self.level * 0.01
     if not common.if_rate(effe_ratio):
         return
     skill = battle.sequence[-1]["action"].skill
     target = battle.sequence[-1]["action"].target
     scope = battle.sequence[-1]["action"].scope
     newobjs = []
     for pt in scope:
         q = battle.map.loc_entity.get(pt, None)
         if q is not None and q.hp > 0 and battle.skill_accept(
                 skill, subject, q):
             newobjs.append(q)
     if len(newobjs) == 0:
         return
     battle.attacked[subject.id] = False
     add_ac = BattleSkillAction(subject=subject,
                                battle=battle,
                                skill=skill,
                                target=target,
                                scope=scope,
                                objects=newobjs,
                                type=SkillType.Turbo,
                                turbotime=turbotime + 1)
     battle.additions.append(add_ac)
     #battle.attacked[subject.id] = False
     if not battle.silent:
         MSG(style=MSG.Effect, subject=subject, effect=self)
Esempio n. 7
0
 def work(self, subject, objects=[], **kwargs):
     battle = kwargs["battle"]
     if subject == battle.sequence[-1]["action"].subject:
         return
     #effe_ratio = self.ratio(subject)
     effe_ratio = 1
     if not common.if_rate(effe_ratio):
         return
     if subject.skill_counter is not None:
         p_tgt = battle.map.location(subject)
         q_tgt = battle.map.location(battle.sequence[-1]["action"].subject)
         if not battle.skill_ava(subject, subject.skill_counter):
             return
         counter_range = battle.map.shape_scope(p_tgt,
                                                subject.skill_counter.shape)
         if q_tgt not in counter_range:
             return
         #dis = battle.map.distance(s_tgt, p_tgt)
         #counter_range = subject.skill_counter.shape.attack_range()
         #if counter_range[0] >= dis or counter_range[1] < dis:
         #    return
         add_ac = BattleSkillAction(
             subject=subject,
             battle=battle,
             skill=subject.skill_counter,
             target=q_tgt,
             scope=[q_tgt],
             objects=[battle.sequence[-1]["action"].subject])
         battle.additions.insert(0, add_ac)
         if not battle.silent:
             MSG(style=MSG.Effect,
                 subject=subject,
                 effect=self,
                 details={
                     "object": battle.sequence[-1]["action"].subject.name
                 })
Esempio n. 8
0
 def do_attack(self):
     """
     战场的攻击行为
     """
     self.battle.sequence.append({
         "current": self.battle.current,
         "action": self,
         "results": {}
     })
     self.battle.check_weapon_before(self.subject, self.skill)
     self.subject.mp_delta += -1 * self.skill.mp
     self.subject.correct()
     #self.battle.add_event(self.subject, BattleEvent.MPChanged, value=self.subject.mp_delta)
     self.critical = False
     self.battle.start_cd(self.subject, self.skill)
     self.skill.work(self.subject,
                     battle=self.battle,
                     phase=BattlePhase.BeforeAttack)
     self.battle.status_work(BattlePhase.BeforeAttack)
     should_hit = common.if_rate(self.subject.hit_rate)
     if not should_hit:
         self.battle.add_event(self.subject, BattleEvent.ACTFault)
     for q in self.objects:
         if self.battle.is_friend(self.subject, q):
             continue
         elif self.subject.hit_rate > 1:
             should_dodge = common.if_rate(1 - (1 - q.dodge_rate) *
                                           self.subject.hit_rate)
         else:
             should_dodge = common.if_rate(q.dodge_rate)
         # 失误与闪避在结果上不做区分,必要时可以通过是否有ACTFault来判断
         if not should_hit or should_dodge:
             self.battle.add_event(q, BattleEvent.ACTMissed)
     # 发动伤害计算前效果,实现得不是很优雅,后面考虑改一下
     self.skill.work(self.subject,
                     battle=self.battle,
                     phase=BattlePhase.BeforeDamage)
     self.battle.status_work(BattlePhase.BeforeDamage)
     for q in self.objects:
         if self.battle.event(q, BattleEvent.ACTMissed) is not None:
             continue
         hp_damaged, mp_damaged, critical, anti_damage = self.battle.damage(
             self.skill, self.subject, q)
         if anti_damage:
             self.battle.add_event(q, BattleEvent.ACTDefended)
             self.anti_list.append(q)
         if critical:
             self.battle.add_event(q, BattleEvent.ACTCritical)
         self.critical = self.critical or critical
         q.hp_delta = -1 * hp_damaged
         q.mp_delta = -1 * mp_damaged
     # 发动伤害计算后效果
     self.skill.work(self.subject,
                     battle=self.battle,
                     phase=BattlePhase.AfterDamage)
     self.battle.status_work(BattlePhase.AfterDamage)
     for q in self.battle.alive:
         q.correct()
         self.battle.add_event(q, BattleEvent.HPDamaged, value=q.hp_delta)
         self.battle.add_event(q, BattleEvent.MPDamaged, value=q.mp_delta)
     for q in self.objects:
         if self.battle.event(self.subject,
                              BattleEvent.ACTFault) is not None:
             break
         should_counter = common.if_rate(q.counter_rate)
         if self.type != SkillType.Counter and should_counter and q.skill_counter is not None:
             self.battle.add_event(q, BattleEvent.Counter)
     self.battle.redirect(self.subject, self.objects, self.target,
                          self.skill)
     # 发动后置效果
     self.skill.work(self.subject,
                     battle=self.battle,
                     phase=BattlePhase.AfterAttack)
     self.battle.status_work(BattlePhase.AfterAttack)
     for q in self.battle.alive:
         q.correct(poison=False)
         q.hp += q.hp_delta
         q.mp += q.mp_delta
         self.battle.add_event(q, BattleEvent.HPChanged, value=q.hp_delta)
         self.battle.add_event(q, BattleEvent.MPChanged, value=q.mp_delta)
     self.battle.check_weapon_after(self.subject, self.skill)
     ## 发动结算后效果
     #if should_hit:
     #    for ef in self.skill.effects:
     #        if ef.phase == BattlePhase.AfterSettlement:
     #            ef.work(self.subject, battle=self.battle)
     #self.battle.status_work(BattlePhase.AfterSettlement)
     for q in reversed(self.objects):
         p_tgt = self.battle.map.location(self.subject)
         #print(q.name)
         q_tgt = self.battle.map.location(q)
         if q.hp > 0 and self.subject.hp > 0 and \
            self.battle.event(q, BattleEvent.Counter) is not None:
             if not self.battle.skill_ava(q, q.skill_counter):
                 continue
             counter_range = self.battle.map.shape_scope(
                 p_tgt, q.skill_counter.shape)
             if q_tgt not in counter_range:
                 continue
             counter_ac = BattleSkillAction(subject=q,
                                            battle=self.battle,
                                            skill=q.skill_counter,
                                            target=p_tgt,
                                            scope=[p_tgt],
                                            objects=[self.subject],
                                            type=SkillType.Counter)
             self.battle.additions.insert(0, counter_ac)