Source code for tuxemon.technique.effects.statchange

# SPDX-License-Identifier: GPL-3.0
# Copyright (c) 2014-2023 William Edwards <shadowapex@gmail.com>, Benjamin Bean <superman2k5@gmail.com>
from __future__ import annotations

import operator
import random
from dataclasses import dataclass
from typing import TYPE_CHECKING

from tuxemon.technique.techeffect import TechEffect, TechEffectResult

if TYPE_CHECKING:
    from tuxemon.monster import Monster
    from tuxemon.technique.technique import Technique


[docs]class StatChangeEffectResult(TechEffectResult): pass
[docs]@dataclass class StatChangeEffect(TechEffect): """ Change combat stats. JSON SYNTAX: value: The number to change the stat by, default is add, use negative to subtract. dividing: Set this to True to divide instead of adding or subtracting the value. overridetofull: In most cases you won't need this. If ``True`` it will set the stat to its original value rather than the specified value, but due to the way the game is coded, it currently only works on hp. """ name = "statchange"
[docs] def apply( self, tech: Technique, user: Monster, target: Monster ) -> StatChangeEffectResult: statsmaster = [ tech.statspeed, tech.stathp, tech.statarmour, tech.statmelee, tech.statranged, tech.statdodge, ] statslugs = [ "speed", "current_hp", "armour", "melee", "ranged", "dodge", ] newstatvalue = 0 for stat, slugdata in zip(statsmaster, statslugs): if not stat: continue value = stat.value max_deviation = stat.max_deviation operation = stat.operation override = stat.overridetofull basestatvalue = getattr(target, slugdata) min_value = value - max_deviation max_value = value + max_deviation if max_deviation: value = random.randint(int(min_value), int(max_value)) if value > 0 and override is not True: ops_dict = { "+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.floordiv, } newstatvalue = ops_dict[operation](basestatvalue, value) if slugdata == "current_hp": if override: target.current_hp = target.hp if newstatvalue <= 0: newstatvalue = 1 setattr(target, slugdata, newstatvalue) return {"success": bool(newstatvalue)}