Extend spawn command (#1777)

* add missing EntityTypes

* small command refactorings and improvements
* move common command patterns and methods to CommandHelpers
* let the spawn command detect the entityType instead of spawning every entity as EntityVehicle
* add extra options for spawning gadgets for better debuging and testing

* More spawn command additions and cleanups+EntityVehicle changes
* Moved remaining patterns from GiveCommand and ClearCommand to CommandHelpers
* Added patterns for hp, maxhp, atk, def and (monster)ai for the spawn command
* Moved intParam parsing via regex to the CommandHelpers
* Read most of EntityVehicle stats from the ConfigGadget instead of hardcoding them

Co-authored-by: hartie95 <mail@hartie95.de>
This commit is contained in:
Alexander Hartmann
2022-09-16 19:04:20 +02:00
committed by GitHub
parent 9671a76af2
commit 08f361954a
9 changed files with 298 additions and 169 deletions

View File

@@ -1,5 +1,7 @@
package emu.grasscutter.game.entity;
import emu.grasscutter.data.binout.ConfigGadget;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.world.Scene;
public abstract class EntityBaseGadget extends GameEntity {
@@ -14,4 +16,30 @@ public abstract class EntityBaseGadget extends GameEntity {
public void onDeath(int killerId) {
super.onDeath(killerId); // Invoke super class's onDeath() method.
}
protected void fillFightProps(ConfigGadget configGadget) {
if (configGadget == null || configGadget.getCombat() == null) {
return;
}
var combatData = configGadget.getCombat();
var combatProperties = combatData.getProperty();
var targetHp = combatProperties.getHP();
setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, targetHp);
setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, targetHp);
if (combatProperties.isInvincible()) {
targetHp = Float.POSITIVE_INFINITY;
}
setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, targetHp);
var atk = combatProperties.getAttack();
setFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK, atk);
setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, atk);
var def = combatProperties.getDefence();
setFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE, def);
setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, def);
setLockHP(combatProperties.isLockHP());
}
}

View File

@@ -60,7 +60,7 @@ public class EntityGadget extends EntityBaseGadget {
this.gadgetId = gadgetId;
this.pos = pos.clone();
this.rot = rot != null ? rot.clone() : new Position();
fillFightProps();
fillFightProps(configGadget);
}
public EntityGadget(Scene scene, int gadgetId, Position pos) {
@@ -72,22 +72,6 @@ public class EntityGadget extends EntityBaseGadget {
this.content = content;
}
private void fillFightProps() {
if (configGadget == null || configGadget.getCombat() == null) {
return;
}
var combatData = configGadget.getCombat();
var combatProperties = combatData.getProperty();
var targetHp = combatProperties.getHP();
setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, targetHp);
if (combatProperties.isInvincible()) {
targetHp = Float.POSITIVE_INFINITY;
}
setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, targetHp);
setLockHP(combatProperties.isLockHP());
}
public GadgetData getGadgetData() {
return data;
}

View File

@@ -37,6 +37,8 @@ import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
import lombok.Getter;
import lombok.Setter;
public class EntityMonster extends GameEntity {
private final MonsterData monsterData;
@@ -48,6 +50,8 @@ public class EntityMonster extends GameEntity {
private final int level;
private int weaponEntityId;
private int poseId;
@Getter @Setter
private int aiId=-1;
public EntityMonster(Scene scene, MonsterData monsterData, Position pos, int level) {
super(scene);
@@ -289,6 +293,9 @@ public class EntityMonster extends GameEntity {
monsterInfo.addWeaponList(weaponInfo);
}
if(this.aiId!=-1){
monsterInfo.setAiConfigId(aiId);
}
entityInfo.setMonster(monsterInfo);

View File

@@ -1,16 +1,18 @@
package emu.grasscutter.game.entity;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.ConfigGadget;
import emu.grasscutter.data.excels.GadgetData;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
import emu.grasscutter.net.proto.FightPropPairOuterClass.*;
import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair;
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
@@ -18,18 +20,18 @@ import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
import emu.grasscutter.net.proto.VehicleInfoOuterClass.*;
import emu.grasscutter.net.proto.VehicleMemberOuterClass.*;
import emu.grasscutter.net.proto.VehicleInfoOuterClass.VehicleInfo;
import emu.grasscutter.net.proto.VehicleMemberOuterClass.VehicleMember;
import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class EntityVehicle extends EntityBaseGadget {
@@ -44,6 +46,7 @@ public class EntityVehicle extends EntityBaseGadget {
@Getter @Setter private float curStamina;
@Getter private List<VehicleMember> vehicleMembers;
@Nullable @Getter private ConfigGadget configGadget;
public EntityVehicle(Scene scene, Player player, int gadgetId, int pointId, Position pos, Position rot) {
super(scene);
@@ -54,21 +57,21 @@ public class EntityVehicle extends EntityBaseGadget {
this.rot = new Position(rot);
this.gadgetId = gadgetId;
this.pointId = pointId;
this.curStamina = 240;
this.vehicleMembers = new ArrayList<VehicleMember>();
switch (gadgetId) {
case 45001001,45001002 -> { // TODO: Not hardcode this. Waverider (skiff)
this.addFightProperty(FightProperty.FIGHT_PROP_BASE_HP, 10000);
this.addFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK, 100);
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, 100);
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 10000);
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, 0);
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_SPEED, 0);
this.addFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, 0);
this.addFightProperty(FightProperty.FIGHT_PROP_MAX_HP, 10000);
}
this.curStamina = 240; // might be in configGadget.GCALKECLLLP.JBAKBEFIMBN.ANBMPHPOALP
this.vehicleMembers = new ArrayList<>();
GadgetData data = GameData.getGadgetDataMap().get(gadgetId);
if (data != null && data.getJsonName() != null) {
this.configGadget = GameData.getGadgetConfigData().get(data.getJsonName());
}
fillFightProps(configGadget);
}
@Override
protected void fillFightProps(ConfigGadget configGadget) {
super.fillFightProps(configGadget);
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_SPEED, 0);
this.addFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, 0);
}
@Override