mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-05-18 00:19:52 +08:00
Handle mob summon and limbo state (#2432)
Mob summon: Something like Monster_Apparatus_Perpetual can summon helper mobs. Ensure these helpers actually get summoned and, on their defeat, possibly change the summoner's mob state. Like, temporarily enter weak state. * Take summon tags from BinOutput/Monster/ConfigMonster_*.json and put them in SceneMonsterInfo * Handle Summon action in ability modifiers from BinOutput/Ability/Temp/MonsterAbilities/ConfigAbility_Monster_*.json * On summoner's kill, also kill the summoned mobs Limbo state: Something like Monster_Invoker_Herald_Water should be invulnerable at a certain HP threshold. Like, shouldn't die when creating their elemental shield. Or, Monster_Apparatus_Perpetual's helper mobs shouldn't die before their summoner. * Look through ConfigAbility (AbilityData in GC) like Invoker_Herald_Water_StateControl. If any AbilityModifier within specifies state Limbo and properties.Actor_HpThresholdRatio, account for this threshold in GameEntity::damage. * Don't let the entity die while in limbo. They will be killed by other events.
This commit is contained in:
committed by
GitHub
Unverified
parent
13c40b53a7
commit
d8c3da8fcd
@@ -1,6 +1,8 @@
|
||||
package emu.grasscutter.game.entity;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.*;
|
||||
import emu.grasscutter.game.ability.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.*;
|
||||
@@ -32,6 +34,8 @@ public abstract class GameEntity {
|
||||
@Getter @Setter private int lastMoveReliableSeq;
|
||||
|
||||
@Getter @Setter private boolean lockHP;
|
||||
private boolean limbo;
|
||||
private float limboHpThreshold;
|
||||
|
||||
@Setter(AccessLevel.PROTECTED)
|
||||
@Getter
|
||||
@@ -110,6 +114,20 @@ public abstract class GameEntity {
|
||||
});
|
||||
}
|
||||
|
||||
protected void setLimbo(float hpThreshold) {
|
||||
limbo = true;
|
||||
limboHpThreshold = hpThreshold;
|
||||
}
|
||||
|
||||
public void onAddAbilityModifier(AbilityModifier data) {
|
||||
// Set limbo state (invulnerability at a certain HP threshold)
|
||||
// if ability modifier calls for it
|
||||
if (data.state == AbilityModifier.State.Limbo &&
|
||||
data.properties != null && data.properties.Actor_HpThresholdRatio > .0f) {
|
||||
this.setLimbo(data.properties.Actor_HpThresholdRatio);
|
||||
}
|
||||
}
|
||||
|
||||
protected MotionInfo getMotionInfo() {
|
||||
return MotionInfo.newBuilder()
|
||||
.setPos(this.getPosition().toProto())
|
||||
@@ -167,11 +185,26 @@ public abstract class GameEntity {
|
||||
return; // If the event is canceled, do not damage the entity.
|
||||
}
|
||||
|
||||
float effectiveDamage = 0;
|
||||
float curHp = getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||
if (curHp != Float.POSITIVE_INFINITY && !lockHP || lockHP && curHp <= event.getDamage()) {
|
||||
// Add negative HP to the current HP property.
|
||||
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -(event.getDamage()));
|
||||
if (limbo) {
|
||||
float maxHp = getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
||||
float curRatio = curHp / maxHp;
|
||||
if (curRatio > limboHpThreshold) {
|
||||
// OK if this hit takes HP below threshold.
|
||||
effectiveDamage = event.getDamage();
|
||||
}
|
||||
if (effectiveDamage >= curHp && limboHpThreshold > .0f) {
|
||||
// Don't let entity die while in limbo.
|
||||
effectiveDamage = curHp - 1;
|
||||
}
|
||||
}
|
||||
else if (curHp != Float.POSITIVE_INFINITY && !lockHP || lockHP && curHp <= event.getDamage()) {
|
||||
effectiveDamage = event.getDamage();
|
||||
}
|
||||
|
||||
// Add negative HP to the current HP property.
|
||||
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -effectiveDamage);
|
||||
|
||||
this.lastAttackType = attackType;
|
||||
this.checkIfDead();
|
||||
|
||||
Reference in New Issue
Block a user