diff --git a/gato/gatos/ABaseGato.py b/gato/gatos/ABaseGato.py index f2885f6..1f6dc68 100644 --- a/gato/gatos/ABaseGato.py +++ b/gato/gatos/ABaseGato.py @@ -154,6 +154,9 @@ class ABaseGato(ABaseItem): energy_loss_reductions: dict[str, float] = {} """Reduces energy loss. The gato or other gatos can add things to it, with a unique key per gato.""" + + bite_chance_reductions: dict[str, float] = {} + """Reduces bite chance. The gato or other gatos can add things to it, with a unique key per gato.""" friendship: float = 1.0 """Friendship stat, starts at 1, max 10.""" @@ -208,6 +211,7 @@ def __init__(self, **kwargs): self.hunger_reductions = {} self.mood_loss_reductions = {} self.energy_loss_reductions = {} + self.bite_chance_reductions = {} for k, v in kwargs.items(): setattr(self, k, v) @@ -276,6 +280,7 @@ def deploy(self, team: list["ABaseGato"]): self.hunger_reductions = {} self.mood_loss_reductions = {} self.energy_loss_reductions = {} + self.bite_chance_reductions = {} if self.health > 0: self._fainted = False @@ -374,7 +379,8 @@ def lose_stats_over_time(self, seconds): self.add_health(-0.02 * seconds) if self.mood < 10: - if random() < self.BITE_CHANCE / self.friendship: + bite_chance = self.BITE_CHANCE * max(0, 1 - sum(self.bite_chance_reductions.values())) + if random() < bite_chance / self.friendship: self._events.append({"bitten": randint(2, 10)}) diff --git a/gato/gatos/LynnGato.py b/gato/gatos/LynnGato.py new file mode 100644 index 0000000..8fbc08d --- /dev/null +++ b/gato/gatos/LynnGato.py @@ -0,0 +1,85 @@ +from ABaseGato import ABaseGato, require_alive + + +class LynnGato(ABaseGato): + # Kit parameters + ALLIES_HP_BUFF_AMOUNT: int = 20 + HP_DECREASE_TIMEFRAME_MINS: int = 30 + HP_DECREASE_AMOUNT: int = 5 + EFF_BOOST_PERCENTAGE: int = 15 + EFF_BOOST_PERCENTAGE_PER_EIDOLON: int = 2 + ALLIES_BITE_CHANCE_REDUCTION_PERCENTAGE: int = 40 + E6_ADDITIONAL_BITE_CHANCE_REDUCTION_PERCENTAGE: int = 40 + + # Kit description + __doc__ = f""" + > Fav Food: + > While deployed, increase all allies health by {ALLIES_HP_BUFF_AMOUNT}. + > Lynn’s health doesn’t deplete, instead every {HP_DECREASE_TIMEFRAME_MINS} minutes Lynn consumes {HP_DECREASE_AMOUNT} health (health doesn’t decrease past 1) + > she increases efficiency by {EFF_BOOST_PERCENTAGE}% and lowers allies base chance to attack the owner/gatos by {ALLIES_BITE_CHANCE_REDUCTION_PERCENTAGE}%. + > Eidolons: e1 -> e5: efficency increases for an additional {EFF_BOOST_PERCENTAGE_PER_EIDOLON}% for each eidolon. + > e6: lowers allies base chance to attack the owner/gatos by an additional {E6_ADDITIONAL_BITE_CHANCE_REDUCTION_PERCENTAGE}%. + """ + + IMAGE = "https://cdn.discordapp.com/attachments/1198010808672723075/1211136378469875712/lynn_gato.png" + # ANIMATIONS = "lynngato" + DISPLAY_NAME = "Red Velvet" + RARITY = 5 + VALUES_TO_SAVE = ABaseGato.VALUES_TO_SAVE + [ + "hp_loss_cooldown", + ] + + LYNN_STATS_UP_EVENT_TYPE = "lynn_stats_up" + EVENT_DESCRIPTIONS = ABaseGato.EVENT_DESCRIPTIONS | { + LYNN_STATS_UP_EVENT_TYPE: "increased all allies' health and reduced their chance to attack the owner!", + } + BUFF_KEY = "lynn_buff_key" + + # Mutable state variables used for this gato + hp_loss_cooldown: int = 0 + + def maybe_lose_health(self, seconds: int): + """Triggers hp loss at fixed time interval (see kit description) and never go below 1 hp.""" + + # Tick down hp loss cd if needed + if self.hp_loss_cooldown > 0: + self.hp_loss_cooldown = max(self.hp_loss_cooldown - seconds, 0) + + # Lose hp if not in cooldown or at min hp + if self.hp_loss_cooldown <= 0 and self.health > 1: + loss_amount = min(self.HP_DECREASE_AMOUNT, self.health - 1) + super().add_health(-loss_amount) + self.hp_loss_cooldown = self.HP_DECREASE_TIMEFRAME_MINS * 60 + + def deploy(self, team: list["ABaseGato"]): + """Increase mood and energy for the team on deploy""" + + # Run base class deploy + super().deploy(team) + + # Apply own efficiency boost + self.efficiency_boosts[self.BUFF_KEY] = ( + self.EFF_BOOST_PERCENTAGE + min(self.eidolon, 5) * self.EFF_BOOST_PERCENTAGE_PER_EIDOLON) / 100 + + # Apply team wide hp buff and bite chance reduction + bite_chance_reduction = self.ALLIES_BITE_CHANCE_REDUCTION_PERCENTAGE / 100 + if self.eidolon >= 6: + bite_chance_reduction += self.E6_ADDITIONAL_BITE_CHANCE_REDUCTION_PERCENTAGE / 100 + for g in team: + g.add_health(self.ALLIES_HP_BUFF_AMOUNT, allow_overflow=True) + g.bite_chance_reductions[self.BUFF_KEY] = bite_chance_reduction + + # Send event + self._events.append({self.LYNN_STATS_UP_EVENT_TYPE: None}) + + def add_health(self, amount: float, allow_overflow: bool = False): + # Block normal health decreases + if amount >= 0: + super().add_health(amount, allow_overflow) + + def simulate(self, team: list["ABaseGato"], seconds: int = 1): + # Apply specialised health decrease mechanic + self.maybe_lose_health(seconds) + + # Then call the parent simulation (VERY IMPORTANT) + super().simulate(team, seconds) diff --git a/gato/gatos/__init__.py b/gato/gatos/__init__.py index 9609da8..10a3082 100644 --- a/gato/gatos/__init__.py +++ b/gato/gatos/__init__.py @@ -15,6 +15,7 @@ import MakGato import KornGato import ExampleGato, LNYGato +import LynnGato import SeeleGato import QingqueGato import HertaGato @@ -34,6 +35,7 @@ importlib.reload(MakGato) importlib.reload(KornGato) importlib.reload(LNYGato) +importlib.reload(LynnGato) importlib.reload(ExampleGato) importlib.reload(SeeleGato) importlib.reload(QingqueGato) @@ -55,6 +57,7 @@ MakGato = MakGato.MakGato KornGato = KornGato.KornGato LNYGato = LNYGato.LNYGato +LynnGato = LynnGato.LynnGato ExampleGato = ExampleGato.ExampleGato SeeleGato = SeeleGato.SeeleGato QingqueGato = QingqueGato.QingqueGato @@ -76,6 +79,7 @@ MakGato, KornGato, LNYGato, + LynnGato, ExampleGato, SeeleGato, QingqueGato,