mirror of
https://github.com/Anime-Game-Servers/Grasscutter-Quests.git
synced 2024-11-26 22:10:26 +00:00
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
This commit is contained in:
parent
d703ec6869
commit
d5e8307611
@ -1,11 +1,28 @@
|
||||
package emu.grasscutter.command;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CommandHelpers {
|
||||
public static final Pattern lvlRegex = Pattern.compile("l(?:vl?)?(\\d+)"); // Java doesn't have raw string literals :(
|
||||
public static final Pattern amountRegex = Pattern.compile("((?<=x)\\d+|\\d+(?=x)(?!x\\d))");
|
||||
public static final Pattern refineRegex = Pattern.compile("r(\\d+)");
|
||||
public static final Pattern rankRegex = Pattern.compile("(\\d+)\\*");
|
||||
public static final Pattern constellationRegex = Pattern.compile("c(\\d+)");
|
||||
public static final Pattern stateRegex = Pattern.compile("state(\\d+)");
|
||||
public static final Pattern blockRegex = Pattern.compile("blk(\\d+)");
|
||||
public static final Pattern groupRegex = Pattern.compile("grp(\\d+)");
|
||||
public static final Pattern configRegex = Pattern.compile("cfg(\\d+)");
|
||||
public static final Pattern hpRegex = Pattern.compile("hp(\\d+)");
|
||||
public static final Pattern maxHPRegex = Pattern.compile("maxhp(\\d+)");
|
||||
public static final Pattern atkRegex = Pattern.compile("atk(\\d+)");
|
||||
public static final Pattern defRegex = Pattern.compile("def(\\d+)");
|
||||
public static final Pattern aiRegex = Pattern.compile("ai(\\d+)");
|
||||
|
||||
public static int matchIntOrNeg(Pattern pattern, String arg) {
|
||||
Matcher match = pattern.matcher(arg);
|
||||
if (match.find()) {
|
||||
@ -13,4 +30,23 @@ public class CommandHelpers {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static <T> List<String> parseIntParameters(List<String> args, @Nonnull T params, Map<Pattern, BiConsumer<T, Integer>> map) {
|
||||
for (int i = args.size() - 1; i >= 0; i--) {
|
||||
String arg = args.get(i).toLowerCase();
|
||||
boolean deleteArg = false;
|
||||
int argNum;
|
||||
for (var entry : map.entrySet()) {
|
||||
if ((argNum = matchIntOrNeg(entry.getKey(), arg)) != -1) {
|
||||
entry.getValue().accept(params, argNum);
|
||||
deleteArg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (deleteArg) {
|
||||
args.remove(i);
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
@ -6,13 +6,15 @@ import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.inventory.Inventory;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.lvlRegex;
|
||||
import static emu.grasscutter.command.CommandHelpers.matchIntOrNeg;
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
|
||||
@Command(
|
||||
label = "clear",
|
||||
@ -20,14 +22,18 @@ import static emu.grasscutter.command.CommandHelpers.matchIntOrNeg;
|
||||
permission = "player.clearinv",
|
||||
permissionTargeted = "player.clearinv.others")
|
||||
public final class ClearCommand implements CommandHandler {
|
||||
private static Pattern refineRegex = Pattern.compile("r(\\d+)");
|
||||
private static Pattern rankRegex = Pattern.compile("(\\d+)\\*");
|
||||
|
||||
private static final Map<Pattern, BiConsumer<ClearItemParameters, Integer>> intCommandHandlers = Map.ofEntries(
|
||||
Map.entry(lvlRegex, ClearItemParameters::setLvl),
|
||||
Map.entry(refineRegex, ClearItemParameters::setRefinement),
|
||||
Map.entry(rankRegex, ClearItemParameters::setRank)
|
||||
);
|
||||
|
||||
private static class ClearItemParameters {
|
||||
public int lvl = 1;
|
||||
public int refinement = 1;
|
||||
public int rank = 4;
|
||||
};
|
||||
@Setter public int lvl = 1;
|
||||
@Setter public int refinement = 1;
|
||||
@Setter public int rank = 4;
|
||||
}
|
||||
|
||||
private Stream<GameItem> getOther(ItemType type, Inventory playerInventory, ClearItemParameters param) {
|
||||
return playerInventory.getItems().values().stream()
|
||||
@ -52,28 +58,8 @@ public final class ClearCommand implements CommandHandler {
|
||||
Inventory playerInventory = targetPlayer.getInventory();
|
||||
ClearItemParameters param = new ClearItemParameters();
|
||||
|
||||
// Extract any tagged arguments (e.g. "lv90", "x100", "r5")
|
||||
for (int i = args.size() - 1; i >= 0; i--) { // Reverse iteration as we are deleting elements
|
||||
String arg = args.get(i).toLowerCase();
|
||||
boolean deleteArg = false;
|
||||
int argNum;
|
||||
// Note that a single argument can actually match all of these, e.g. "lv90r5*"
|
||||
if ((argNum = matchIntOrNeg(lvlRegex, arg)) != -1) {
|
||||
param.lvl = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(refineRegex, arg)) != -1) {
|
||||
param.refinement = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(rankRegex, arg)) != -1) {
|
||||
param.rank = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if (deleteArg) {
|
||||
args.remove(i);
|
||||
}
|
||||
}
|
||||
// Extract any tagged int arguments (e.g. "lv90", "x100", "r5")
|
||||
parseIntParameters(args, param, intCommandHandlers);
|
||||
|
||||
if (args.size() < 1) {
|
||||
sendUsageMessage(sender);
|
||||
|
@ -15,10 +15,12 @@ import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.utils.SparseSet;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
@ -33,9 +35,6 @@ import static emu.grasscutter.command.CommandHelpers.*;
|
||||
permissionTargeted = "player.give.others",
|
||||
threading = true)
|
||||
public final class GiveCommand implements CommandHandler {
|
||||
private static Pattern refineRegex = Pattern.compile("r(\\d+)");
|
||||
private static Pattern constellationRegex = Pattern.compile("c(\\d+)");
|
||||
|
||||
private enum GiveAllType {
|
||||
NONE,
|
||||
ALL,
|
||||
@ -44,48 +43,31 @@ public final class GiveCommand implements CommandHandler {
|
||||
AVATARS
|
||||
}
|
||||
|
||||
private static final Map<Pattern, BiConsumer<GiveItemParameters, Integer>> intCommandHandlers = Map.ofEntries(
|
||||
Map.entry(lvlRegex, GiveItemParameters::setLvl),
|
||||
Map.entry(refineRegex, GiveItemParameters::setRefinement),
|
||||
Map.entry(amountRegex, GiveItemParameters::setAmount),
|
||||
Map.entry(constellationRegex, GiveItemParameters::setConstellation)
|
||||
);
|
||||
|
||||
private static class GiveItemParameters {
|
||||
public int id;
|
||||
public int lvl = 0;
|
||||
public int amount = 1;
|
||||
public int refinement = 1;
|
||||
public int constellation = -1;
|
||||
@Setter public int lvl = 0;
|
||||
@Setter public int amount = 1;
|
||||
@Setter public int refinement = 1;
|
||||
@Setter public int constellation = -1;
|
||||
public int mainPropId = -1;
|
||||
public List<Integer> appendPropIdList;
|
||||
public ItemData data;
|
||||
public AvatarData avatarData;
|
||||
public GiveAllType giveAllType = GiveAllType.NONE;
|
||||
};
|
||||
}
|
||||
|
||||
private GiveItemParameters parseArgs(Player sender, List<String> args) throws IllegalArgumentException {
|
||||
GiveItemParameters param = new GiveItemParameters();
|
||||
|
||||
// Extract any tagged arguments (e.g. "lv90", "x100", "r5")
|
||||
for (int i = args.size() - 1; i >= 0; i--) { // Reverse iteration as we are deleting elements
|
||||
String arg = args.get(i).toLowerCase();
|
||||
boolean deleteArg = false;
|
||||
int argNum;
|
||||
// Note that a single argument can actually match all of these, e.g. "lv90r5x100"
|
||||
if ((argNum = matchIntOrNeg(lvlRegex, arg)) != -1) {
|
||||
param.lvl = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(refineRegex, arg)) != -1) {
|
||||
param.refinement = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(constellationRegex, arg)) != -1) {
|
||||
param.constellation = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(amountRegex, arg)) != -1) {
|
||||
param.amount = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if (deleteArg) {
|
||||
args.remove(i);
|
||||
}
|
||||
}
|
||||
parseIntParameters(args, param, intCommandHandlers);
|
||||
|
||||
// At this point, first remaining argument MUST be itemId/avatarId
|
||||
if (args.size() < 1) {
|
||||
|
@ -9,78 +9,49 @@ import emu.grasscutter.data.excels.MonsterData;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import static emu.grasscutter.config.Configuration.*;
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(
|
||||
label = "spawn",
|
||||
aliases = {"drop"},
|
||||
usage = {
|
||||
"(<itemId>|<monsterId|gadgetId>) [x<amount>] [lv<level>(monster only)] [state<state>(gadget only)] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>"},
|
||||
"<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<gadgetId> [x<amount>] [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<monsterId> [x<amount>] [lv<level>] [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>"},
|
||||
permission = "server.spawn",
|
||||
permissionTargeted = "server.spawn.others")
|
||||
public final class SpawnCommand implements CommandHandler {
|
||||
private static final Pattern stateRegex = Pattern.compile("state(\\d+)");
|
||||
private static final Pattern blockRegex = Pattern.compile("blk(\\d+)");
|
||||
private static final Pattern groupRegex = Pattern.compile("grp(\\d+)");
|
||||
private static final Pattern configRegex = Pattern.compile("cfg(\\d+)");
|
||||
|
||||
private static class SpawnParameters {
|
||||
public int id;
|
||||
public int lvl = 1;
|
||||
public int amount = 1;
|
||||
public int blockId = -1;
|
||||
public int groupId = -1;
|
||||
public int configId = -1;
|
||||
public int state = -1;
|
||||
public Position pos = null;
|
||||
};
|
||||
private static final Map<Pattern, BiConsumer<SpawnParameters, Integer>> intCommandHandlers = Map.ofEntries(
|
||||
Map.entry(lvlRegex, SpawnParameters::setLvl),
|
||||
Map.entry(amountRegex, SpawnParameters::setAmount),
|
||||
Map.entry(stateRegex, SpawnParameters::setState),
|
||||
Map.entry(blockRegex, SpawnParameters::setBlockId),
|
||||
Map.entry(groupRegex, SpawnParameters::setGroupId),
|
||||
Map.entry(configRegex, SpawnParameters::setConfigId),
|
||||
Map.entry(maxHPRegex, SpawnParameters::setMaxHP),
|
||||
Map.entry(hpRegex, SpawnParameters::setHp),
|
||||
Map.entry(defRegex, SpawnParameters::setDef),
|
||||
Map.entry(atkRegex, SpawnParameters::setAtk),
|
||||
Map.entry(aiRegex, SpawnParameters::setAi)
|
||||
);
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
SpawnParameters param = new SpawnParameters();
|
||||
|
||||
// Extract any tagged arguments (e.g. "lv90", "x100", "state105")
|
||||
for (int i = args.size() - 1; i >= 0; i--) { // Reverse iteration as we are deleting elements
|
||||
String arg = args.get(i).toLowerCase();
|
||||
boolean deleteArg = false;
|
||||
int argNum;
|
||||
// Note that a single argument can actually match all of these, e.g. "lv90r5x100"
|
||||
if ((argNum = matchIntOrNeg(lvlRegex, arg)) != -1) {
|
||||
param.lvl = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(amountRegex, arg)) != -1) {
|
||||
param.amount = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(stateRegex, arg)) != -1) {
|
||||
param.state = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(blockRegex, arg)) != -1) {
|
||||
param.blockId = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(groupRegex, arg)) != -1) {
|
||||
param.groupId = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if ((argNum = matchIntOrNeg(configRegex, arg)) != -1) {
|
||||
param.configId = argNum;
|
||||
deleteArg = true;
|
||||
}
|
||||
if (deleteArg) {
|
||||
args.remove(i);
|
||||
}
|
||||
}
|
||||
parseIntParameters(args, param, intCommandHandlers);
|
||||
|
||||
// At this point, first remaining argument MUST be the id and the rest the pos
|
||||
if (args.size() < 1) {
|
||||
@ -94,7 +65,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
x = Float.parseFloat(args.get(1));
|
||||
y = Float.parseFloat(args.get(2));
|
||||
z = Float.parseFloat(args.get(3));
|
||||
param.pos = new Position(x,y,z);
|
||||
param.pos = new Position(x, y, z);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
@ -118,10 +89,10 @@ public final class SpawnCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
Scene scene = targetPlayer.getScene();
|
||||
param.scene = targetPlayer.getScene();
|
||||
|
||||
if (scene.getEntities().size() + param.amount > GAME_OPTIONS.sceneEntityLimit) {
|
||||
param.amount = Math.max(Math.min(GAME_OPTIONS.sceneEntityLimit - scene.getEntities().size(), param.amount), 0);
|
||||
if (param.scene.getEntities().size() + param.amount > GAME_OPTIONS.sceneEntityLimit) {
|
||||
param.amount = Math.max(Math.min(GAME_OPTIONS.sceneEntityLimit - param.scene.getEntities().size(), param.amount), 0);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.limit_reached", param.amount));
|
||||
if (param.amount <= 0) {
|
||||
return;
|
||||
@ -129,7 +100,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
double maxRadius = Math.sqrt(param.amount * 0.2 / Math.PI);
|
||||
if(param.pos==null){
|
||||
if (param.pos == null) {
|
||||
param.pos = targetPlayer.getPosition();
|
||||
}
|
||||
|
||||
@ -137,37 +108,77 @@ public final class SpawnCommand implements CommandHandler {
|
||||
Position pos = GetRandomPositionInCircle(param.pos, maxRadius).addY(3);
|
||||
GameEntity entity = null;
|
||||
if (itemData != null) {
|
||||
entity = new EntityItem(scene, null, itemData, pos, 1, true);
|
||||
entity = createItem(itemData, param, pos);
|
||||
}
|
||||
if (gadgetData != null) {
|
||||
pos.addY(-3);
|
||||
if(gadgetData.getType() == EntityType.Vehicle) {
|
||||
entity = new EntityVehicle(scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
|
||||
} else {
|
||||
entity = new EntityGadget(scene, param.id, pos, targetPlayer.getRotation());
|
||||
if(param.state!=-1){
|
||||
((EntityGadget)entity).setState(param.state);
|
||||
}
|
||||
}
|
||||
entity = createGadget(gadgetData, param, pos, targetPlayer);
|
||||
}
|
||||
if (monsterData != null) {
|
||||
entity = new EntityMonster(scene, monsterData, pos, param.lvl);
|
||||
}
|
||||
if(param.blockId!=-1){
|
||||
entity.setBlockId(param.blockId);
|
||||
}
|
||||
if(param.groupId!=-1){
|
||||
entity.setGroupId(param.groupId);
|
||||
}
|
||||
if(param.configId!=-1){
|
||||
entity.setConfigId(param.configId);
|
||||
entity = createMonster(monsterData, param, pos);
|
||||
}
|
||||
applyCommonParameters(entity, param);
|
||||
|
||||
scene.addEntity(entity);
|
||||
param.scene.addEntity(entity);
|
||||
}
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.success", param.amount, param.id));
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) {
|
||||
return new EntityItem(param.scene, null, itemData, pos, 1, true);
|
||||
}
|
||||
|
||||
private EntityMonster createMonster(MonsterData monsterData, SpawnParameters param, Position pos) {
|
||||
var entity = new EntityMonster(param.scene, monsterData, pos, param.lvl);
|
||||
if (param.ai != -1) {
|
||||
entity.setAiId(param.ai);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
private EntityBaseGadget createGadget(GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) {
|
||||
EntityBaseGadget entity;
|
||||
if (gadgetData.getType() == EntityType.Vehicle) {
|
||||
entity = new EntityVehicle(param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
|
||||
} else {
|
||||
entity = new EntityGadget(param.scene, param.id, pos, targetPlayer.getRotation());
|
||||
if (param.state != -1) {
|
||||
((EntityGadget) entity).setState(param.state);
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void applyCommonParameters(GameEntity entity, SpawnParameters param) {
|
||||
if (param.blockId != -1) {
|
||||
entity.setBlockId(param.blockId);
|
||||
}
|
||||
if (param.groupId != -1) {
|
||||
entity.setGroupId(param.groupId);
|
||||
}
|
||||
if (param.configId != -1) {
|
||||
entity.setConfigId(param.configId);
|
||||
}
|
||||
if (param.maxHP != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, param.maxHP);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, param.maxHP);
|
||||
}
|
||||
if (param.hp != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, param.hp == 0 ? Float.MAX_VALUE : param.hp);
|
||||
}
|
||||
if (param.atk != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_ATTACK, param.atk);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk);
|
||||
}
|
||||
if (param.def != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_DEFENSE, param.def);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def);
|
||||
}
|
||||
}
|
||||
|
||||
private Position GetRandomPositionInCircle(Position origin, double radius) {
|
||||
Position target = origin.clone();
|
||||
double angle = Math.random() * 360;
|
||||
@ -175,4 +186,21 @@ public final class SpawnCommand implements CommandHandler {
|
||||
target.addX((float) (r * Math.cos(angle))).addZ((float) (r * Math.sin(angle)));
|
||||
return target;
|
||||
}
|
||||
|
||||
private static class SpawnParameters {
|
||||
@Setter public int id;
|
||||
@Setter public int lvl = 1;
|
||||
@Setter public int amount = 1;
|
||||
@Setter public int blockId = -1;
|
||||
@Setter public int groupId = -1;
|
||||
@Setter public int configId = -1;
|
||||
@Setter public int state = -1;
|
||||
@Setter public int hp = -1;
|
||||
@Setter public int maxHP = -1;
|
||||
@Setter public int atk = -1;
|
||||
@Setter public int def = -1;
|
||||
@Setter public int ai = -1;
|
||||
@Setter public Position pos = null;
|
||||
public Scene scene = null;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user