Fix something and implement weapon entities

This commit is contained in:
StartForKiller
2023-05-30 18:22:43 -04:00
committed by KingRainbow44
parent 16ec2e3d40
commit 815ba3e3e3
9 changed files with 137 additions and 27 deletions

View File

@@ -3,13 +3,10 @@ package emu.grasscutter.data.common;
import emu.grasscutter.data.excels.ProudSkillData; import emu.grasscutter.data.excels.ProudSkillData;
import emu.grasscutter.game.ability.Ability; import emu.grasscutter.game.ability.Ability;
import it.unimi.dsi.fastutil.floats.FloatArrayList; import it.unimi.dsi.fastutil.floats.FloatArrayList;
import it.unimi.dsi.fastutil.objects.Object2FloatArrayMap; import it.unimi.dsi.fastutil.objects.*;
import it.unimi.dsi.fastutil.objects.Object2FloatMap; import lombok.*;
import java.util.List;
import java.util.NoSuchElementException; import java.util.*;
import java.util.Optional;
import lombok.Getter;
import lombok.val;
@Getter @Getter
public class DynamicFloat { public class DynamicFloat {
@@ -114,6 +111,7 @@ public class DynamicFloat {
s = s.substring(1); s = s.substring(1);
} else if (s.startsWith("-%")) { } else if (s.startsWith("-%")) {
s = s.substring(2); s = s.substring(2);
negative = true;
} }
this.op = Op.KEY; this.op = Op.KEY;

View File

@@ -8,6 +8,7 @@ import emu.grasscutter.data.ResourceType;
public class CodexWeaponData extends GameResource { public class CodexWeaponData extends GameResource {
private int Id; private int Id;
private int weaponId; private int weaponId;
private int gadgetId;
private int sortOrder; private int sortOrder;
public int getSortOrder() { public int getSortOrder() {
@@ -18,6 +19,10 @@ public class CodexWeaponData extends GameResource {
return weaponId; return weaponId;
} }
public int getGadgetId() {
return weaponId;
}
public int getId() { public int getId() {
return Id; return Id;
} }

View File

@@ -32,6 +32,8 @@ public class ActionSetGlobalValueToOverrideMap extends AbilityActionHandler {
entity.getGlobalAbilityValues().put(globalValueKey, globalValue); entity.getGlobalAbilityValues().put(globalValueKey, globalValue);
//TODO: ChangeServerGlobalValueNotify
return true; return true;
} }
} }

View File

@@ -25,6 +25,7 @@ import emu.grasscutter.data.excels.weapon.WeaponCurveData;
import emu.grasscutter.data.excels.weapon.WeaponPromoteData; import emu.grasscutter.data.excels.weapon.WeaponPromoteData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.entity.EntityWeapon;
import emu.grasscutter.game.inventory.EquipType; import emu.grasscutter.game.inventory.EquipType;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType; import emu.grasscutter.game.inventory.ItemType;
@@ -459,10 +460,14 @@ public class Avatar {
} }
// Set equip // Set equip
getEquips().put(itemEquipType.getValue(), item); this.getEquips().put(itemEquipType.getValue(), item);
if (itemEquipType == EquipType.EQUIP_WEAPON && getPlayer().getWorld() != null) { if (itemEquipType == EquipType.EQUIP_WEAPON && getPlayer().getWorld() != null) {
item.setWeaponEntityId(this.getPlayer().getWorld().getNextEntityId(EntityIdType.WEAPON)); if (!(item.getWeaponEntity() != null && item.getWeaponEntity().getScene() == getPlayer().getScene())) {
item.setWeaponEntity(new EntityWeapon(this.getPlayer().getScene(), item.getItemData().getGadgetId()));
this.getPlayer().getScene().getWeaponEntities().put(item.getWeaponEntity().getId(), item.getWeaponEntity());
}
//item.setWeaponEntityId(this.getPlayer().getWorld().getNextEntityId(EntityIdType.WEAPON));
} }
item.setEquipCharacter(this.getAvatarId()); item.setEquipCharacter(this.getAvatarId());
@@ -1257,7 +1262,11 @@ public class Avatar {
item.setEquipCharacter(this.getAvatarId()); item.setEquipCharacter(this.getAvatarId());
item.setOwner(player); item.setOwner(player);
if (item.getItemData().getEquipType() == EquipType.EQUIP_WEAPON) { if (item.getItemData().getEquipType() == EquipType.EQUIP_WEAPON) {
item.setWeaponEntityId(player.getWorld().getNextEntityId(EntityIdType.WEAPON)); if (!(item.getWeaponEntity() != null && item.getWeaponEntity().getScene() == player.getScene())) {
item.setWeaponEntity(new EntityWeapon(player.getScene(), item.getItemData().getGadgetId()));
player.getScene().getWeaponEntities().put(item.getWeaponEntity().getId(), item.getWeaponEntity());
}
player.sendPacket(new PacketAvatarEquipChangeNotify(this, item)); player.sendPacket(new PacketAvatarEquipChangeNotify(this, item));
} }
}); });

View File

@@ -63,7 +63,10 @@ public class EntityAvatar extends GameEntity {
var weapon = this.getAvatar().getWeapon(); var weapon = this.getAvatar().getWeapon();
if (weapon != null) { if (weapon != null) {
weapon.setWeaponEntityId(world.getNextEntityId(EntityIdType.WEAPON)); if (!(weapon.getWeaponEntity() != null && weapon.getWeaponEntity().getScene() == scene)) {
weapon.setWeaponEntity(new EntityWeapon(this.getPlayer().getScene(), weapon.getItemData().getGadgetId()));
scene.getWeaponEntities().put(weapon.getWeaponEntity().getId(), weapon.getWeaponEntity());
}
} }
} else { } else {
Grasscutter.getLogger() Grasscutter.getLogger()
@@ -107,7 +110,10 @@ public class EntityAvatar extends GameEntity {
*/ */
public int getWeaponEntityId() { public int getWeaponEntityId() {
var avatar = this.getAvatar(); var avatar = this.getAvatar();
return avatar.getWeapon() == null ? 0 : avatar.getWeapon().getWeaponEntityId();
if (avatar.getWeapon() != null && avatar.getWeapon().getWeaponEntity() != null) {
return avatar.getWeapon().getWeaponEntity().getId();
} else return 0;
} }
@Override @Override

View File

@@ -55,7 +55,7 @@ public class EntityMonster extends GameEntity {
@Getter private final ConfigEntityMonster configEntityMonster; @Getter private final ConfigEntityMonster configEntityMonster;
@Getter private final Position bornPos; @Getter private final Position bornPos;
@Getter private final int level; @Getter private final int level;
@Getter private int weaponEntityId; @Getter private EntityWeapon weaponEntity;
@Getter @Setter private int poseId; @Getter @Setter private int poseId;
@Getter @Setter private int aiId = -1; @Getter @Setter private int aiId = -1;
@@ -81,7 +81,9 @@ public class EntityMonster extends GameEntity {
// Monster weapon // Monster weapon
if (getMonsterWeaponId() > 0) { if (getMonsterWeaponId() > 0) {
this.weaponEntityId = getWorld().getNextEntityId(EntityIdType.WEAPON); this.weaponEntity = new EntityWeapon(scene, getMonsterWeaponId());
scene.getWeaponEntities().put(this.weaponEntity.getId(), this.weaponEntity);
//this.weaponEntityId = getWorld().getNextEntityId(EntityIdType.WEAPON);
} }
this.recalcStats(); this.recalcStats();
@@ -349,7 +351,7 @@ public class EntityMonster extends GameEntity {
if (this.getMonsterWeaponId() > 0) { if (this.getMonsterWeaponId() > 0) {
SceneWeaponInfo weaponInfo = SceneWeaponInfo.newBuilder() SceneWeaponInfo weaponInfo = SceneWeaponInfo.newBuilder()
.setEntityId(this.weaponEntityId) .setEntityId(this.getWeaponEntity() != null ? this.getWeaponEntity().getId() : 0)
.setGadgetId(this.getMonsterWeaponId()) .setGadgetId(this.getMonsterWeaponId())
.setAbilityInfo(AbilitySyncStateInfo.newBuilder()) .setAbilityInfo(AbilitySyncStateInfo.newBuilder())
.build(); .build();

View File

@@ -0,0 +1,85 @@
package emu.grasscutter.game.entity;
import javax.annotation.Nullable;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.AbilityData;
import emu.grasscutter.data.binout.config.ConfigEntityGadget;
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
import emu.grasscutter.data.excels.GadgetData;
import emu.grasscutter.game.entity.gadget.GadgetContent;
import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.grasscutter.scripts.EntityControllerScriptManager;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ToString(callSuper = true)
public class EntityWeapon extends EntityBaseGadget {
@Getter private final GadgetData gadgetData;
@Getter(onMethod = @__(@Override)) @Setter
private int gadgetId;
@Nullable @Getter
private ConfigEntityGadget configGadget;
@Getter(onMethod = @__(@Override), lazy = true)
private final Int2FloatMap fightProperties = new Int2FloatOpenHashMap();
@Getter private final Position bornPos;
@Getter private final Position bornRot;
public EntityWeapon(Scene scene, int gadgetId) {
super(scene);
this.gadgetData = GameData.getGadgetDataMap().get(gadgetId);
if (gadgetData!=null && gadgetData.getJsonName()!=null) {
this.configGadget = GameData.getGadgetConfigData().get(gadgetData.getJsonName());
}
this.gadgetId = gadgetId;
this.gadgetId = gadgetId;
this.bornPos = this.getPosition().clone();
this.bornRot = this.getRotation().clone();
fillFightProps(configGadget);
if(GameData.getGadgetMappingMap().containsKey(gadgetId)) {
String controllerName = GameData.getGadgetMappingMap().get(gadgetId).getServerController();
setEntityController(EntityControllerScriptManager.getGadgetController(controllerName));
if(getEntityController() == null) {
Grasscutter.getLogger().warn("Gadget controller {} not found", controllerName);
}
}
this.id = scene.getWorld().getNextEntityId(EntityIdType.WEAPON);
Grasscutter.getLogger().warn("New weapon entity id {} at scene {}", this.id, this.getScene().getId());
initAbilities();
}
private void addConfigAbility(ConfigAbilityData abilityData){
AbilityData data = GameData.getAbilityData(abilityData.getAbilityName());
if(data != null)
getScene().getWorld().getHost().getAbilityManager().addAbilityToEntity(
this, data);
}
@Override
public void initAbilities() {
//TODO: handle predynamic, static and dynamic here
if(this.configGadget != null && this.configGadget.getAbilities() != null) {
for (var ability : this.configGadget.getAbilities()) {
addConfigAbility(ability);
}
}
}
@Override
public SceneEntityInfo toProto() {
return null;
}
}

View File

@@ -8,6 +8,7 @@ import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData; import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData; import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.entity.EntityWeapon;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo; import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
@@ -56,7 +57,7 @@ public class GameItem {
@Getter private List<Integer> appendPropIdList; @Getter private List<Integer> appendPropIdList;
@Getter @Setter private int equipCharacter; @Getter @Setter private int equipCharacter;
@Transient @Getter @Setter private int weaponEntityId; @Transient @Getter @Setter private EntityWeapon weaponEntity;
@Transient @Getter private boolean newItem = false; @Transient @Getter private boolean newItem = false;
public GameItem() { public GameItem() {
@@ -275,14 +276,13 @@ public class GameItem {
} }
public SceneWeaponInfo createSceneWeaponInfo() { public SceneWeaponInfo createSceneWeaponInfo() {
SceneWeaponInfo.Builder weaponInfo = var weaponInfo = SceneWeaponInfo.newBuilder()
SceneWeaponInfo.newBuilder() .setEntityId(this.getWeaponEntity() != null ? this.getWeaponEntity().getId() : 0)
.setEntityId(this.getWeaponEntityId()) .setItemId(this.getItemId())
.setItemId(this.getItemId()) .setGuid(this.getGuid())
.setGuid(this.getGuid()) .setLevel(this.getLevel())
.setLevel(this.getLevel()) .setGadgetId(this.getItemData().getGadgetId())
.setGadgetId(this.getItemData().getGadgetId()) .setAbilityInfo(AbilitySyncStateInfo.newBuilder().setIsInited(getAffixes().size() > 0));
.setAbilityInfo(AbilitySyncStateInfo.newBuilder().setIsInited(getAffixes().size() > 0));
if (this.getAffixes() != null && this.getAffixes().size() > 0) { if (this.getAffixes() != null && this.getAffixes().size() > 0) {
for (int affix : this.getAffixes()) { for (int affix : this.getAffixes()) {

View File

@@ -55,6 +55,7 @@ public final class Scene {
@Getter private final SceneData sceneData; @Getter private final SceneData sceneData;
@Getter private final List<Player> players; @Getter private final List<Player> players;
@Getter private final Map<Integer, GameEntity> entities; @Getter private final Map<Integer, GameEntity> entities;
@Getter private final Map<Integer, GameEntity> weaponEntities;
@Getter private final Set<SpawnDataEntry> spawnedEntities; @Getter private final Set<SpawnDataEntry> spawnedEntities;
@Getter private final Set<SpawnDataEntry> deadSpawnedEntities; @Getter private final Set<SpawnDataEntry> deadSpawnedEntities;
@Getter private final Set<SceneBlock> loadedBlocks; @Getter private final Set<SceneBlock> loadedBlocks;
@@ -85,6 +86,7 @@ public final class Scene {
this.sceneData = sceneData; this.sceneData = sceneData;
this.players = new CopyOnWriteArrayList<>(); this.players = new CopyOnWriteArrayList<>();
this.entities = new ConcurrentHashMap<>(); this.entities = new ConcurrentHashMap<>();
this.weaponEntities = new ConcurrentHashMap<>();
this.prevScene = 3; this.prevScene = 3;
this.sceneRoutes = GameData.getSceneRoutes(getId()); this.sceneRoutes = GameData.getSceneRoutes(getId());
@@ -126,8 +128,9 @@ public final class Scene {
// Check for an avatar. // Check for an avatar.
var entity = this.entities.get(id); var entity = this.entities.get(id);
if (entity == null && (id >> 24) == EntityType.Avatar.getValue()) { if (entity == null) entity = this.weaponEntities.get(id);
for (var player : this.getPlayers()) { if (entity == null && (id >> 24) == EntityIdType.AVATAR.getId()) {
for (var player : getPlayers()) {
for (var avatar : player.getTeamManager().getActiveTeam()) { for (var avatar : player.getTeamManager().getActiveTeam()) {
if (avatar.getId() == id) return avatar; if (avatar.getId() == id) return avatar;
} }
@@ -797,7 +800,7 @@ public final class Scene {
for (GameEntity entity : this.getEntities().values()) { for (GameEntity entity : this.getEntities().values()) {
var spawnEntry = entity.getSpawnEntry(); var spawnEntry = entity.getSpawnEntry();
if (spawnEntry != null && !visible.contains(spawnEntry)) { if (spawnEntry != null && !(entity instanceof EntityWeapon) && !visible.contains(spawnEntry)) {
toRemove.add(entity); toRemove.add(entity);
spawnedEntities.remove(spawnEntry); spawnedEntities.remove(spawnEntry);
} }