From 5feabc8f9a7c341d1d7f66a6a6b1b6e084a53f87 Mon Sep 17 00:00:00 2001 From: Melledy <52122272+Melledy@users.noreply.github.com> Date: Tue, 19 Jul 2022 02:51:26 -0700 Subject: [PATCH] Add `Entity::OnInteract` --- .../grasscutter/game/entity/EntityGadget.java | 20 ++++++-- .../grasscutter/game/entity/EntityItem.java | 28 +++++++++++ .../game/entity/EntityMonster.java | 6 +++ .../game/entity/EntityVehicle.java | 6 +++ .../grasscutter/game/entity/GameEntity.java | 11 ++++ .../game/entity/gadget/GadgetChest.java | 7 +-- .../emu/grasscutter/game/player/Player.java | 50 +++---------------- .../emu/grasscutter/game/world/Scene.java | 30 +++++++---- 8 files changed, 97 insertions(+), 61 deletions(-) diff --git a/src/main/java/emu/grasscutter/game/entity/EntityGadget.java b/src/main/java/emu/grasscutter/game/entity/EntityGadget.java index fe2b60f75..2d84cafa4 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityGadget.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityGadget.java @@ -3,6 +3,7 @@ package emu.grasscutter.game.entity; import emu.grasscutter.data.GameData; import emu.grasscutter.data.excels.GadgetData; import emu.grasscutter.game.entity.gadget.*; +import emu.grasscutter.game.player.Player; import emu.grasscutter.game.props.EntityIdType; import emu.grasscutter.game.props.EntityType; import emu.grasscutter.game.props.LifeState; @@ -15,6 +16,7 @@ import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityIn import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData; import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo; import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair; +import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; import emu.grasscutter.net.proto.PropPairOuterClass.PropPair; import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType; @@ -22,6 +24,7 @@ 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.VisionTypeOuterClass.VisionType; import emu.grasscutter.scripts.constants.EventType; import emu.grasscutter.scripts.data.SceneGadget; import emu.grasscutter.scripts.data.ScriptArgs; @@ -150,6 +153,19 @@ public class EntityGadget extends EntityBaseGadget { if (this.fightProp == null) this.fightProp = new Int2FloatOpenHashMap(); return this.fightProp; } + + @Override + public void onInteract(Player player, GadgetInteractReq interactReq) { + if (this.getContent() == null) { + return; + } + + boolean shouldDelete = this.getContent().onInteract(player, interactReq); + + if (shouldDelete) { + this.getScene().killEntity(this); + } + } @Override public void onCreate() { @@ -213,8 +229,4 @@ public class EntityGadget extends EntityBaseGadget { return entityInfo.build(); } - public void die() { - getScene().broadcastPacket(new PacketLifeStateChangeNotify(this, LifeState.LIFE_DEAD)); - this.onDeath(0); - } } diff --git a/src/main/java/emu/grasscutter/game/entity/EntityItem.java b/src/main/java/emu/grasscutter/game/entity/EntityItem.java index 791b230a1..63817f7c1 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityItem.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityItem.java @@ -3,6 +3,7 @@ package emu.grasscutter.game.entity; import emu.grasscutter.data.excels.ItemData; import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.player.Player; +import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.EntityIdType; import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.world.Scene; @@ -12,6 +13,8 @@ import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityIn import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData; import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo; import emu.grasscutter.net.proto.GadgetBornTypeOuterClass.GadgetBornType; +import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; +import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType; import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; import emu.grasscutter.net.proto.PropPairOuterClass.PropPair; import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType; @@ -19,6 +22,7 @@ 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.server.packet.send.PacketGadgetInteractRsp; import emu.grasscutter.utils.Position; import emu.grasscutter.utils.ProtoHelper; import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; @@ -99,6 +103,30 @@ public class EntityItem extends EntityBaseGadget { public boolean isShare() { return share; } + + @Override + public void onInteract(Player player, GadgetInteractReq interactReq) { + // check drop owner to avoid someone picked up item in others' world + if (!this.isShare()) { + int dropOwner = (int) (this.getGuid() >> 32); + if (dropOwner != player.getUid()) { + return; + } + } + + this.getScene().removeEntity(this); + GameItem item = new GameItem(this.getItemData(), this.getCount()); + + // Add to inventory + boolean success = player.getInventory().addItem(item, ActionReason.SubfieldDrop); + if (success) { + if (!this.isShare()) { // not shared drop + player.sendPacket(new PacketGadgetInteractRsp(this, InteractType.INTERACT_TYPE_PICK_ITEM)); + } else { + this.getScene().broadcastPacket(new PacketGadgetInteractRsp(this, InteractType.INTERACT_TYPE_PICK_ITEM)); + } + } + } @Override public SceneEntityInfo toProto() { diff --git a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java index b8c47e3db..eacc0ca60 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java @@ -16,6 +16,7 @@ import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityIn import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData; import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo; import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair; +import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.MonsterBornTypeOuterClass.MonsterBornType; import emu.grasscutter.net.proto.PropPairOuterClass.PropPair; import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType; @@ -112,6 +113,11 @@ public class EntityMonster extends GameEntity { this.poseId = poseId; } + @Override + public void onInteract(Player player, GadgetInteractReq interactReq) { + player.getInsectCaptureManager().arrestSmallCreature(this); + } + @Override public void onCreate() { // Lua event diff --git a/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java b/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java index ceab84bc3..a8381b8d8 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java @@ -10,6 +10,7 @@ import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.Animat 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.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; import emu.grasscutter.net.proto.PropPairOuterClass.PropPair; import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType; @@ -82,6 +83,11 @@ public class EntityVehicle extends EntityBaseGadget { public Position getRotation() { return this.rot; } + + @Override + public void onInteract(Player player, GadgetInteractReq interactReq) { + player.getInsectCaptureManager().arrestSmallCreature(this); + } @Override public SceneEntityInfo toProto() { diff --git a/src/main/java/emu/grasscutter/game/entity/GameEntity.java b/src/main/java/emu/grasscutter/game/entity/GameEntity.java index 21d8f8173..c571f54f0 100644 --- a/src/main/java/emu/grasscutter/game/entity/GameEntity.java +++ b/src/main/java/emu/grasscutter/game/entity/GameEntity.java @@ -3,12 +3,14 @@ package emu.grasscutter.game.entity; import java.util.HashMap; import java.util.Map; +import emu.grasscutter.game.player.Player; import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.LifeState; import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.SpawnDataEntry; import emu.grasscutter.game.world.World; import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair; +import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState; import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo; @@ -228,6 +230,15 @@ public abstract class GameEntity { } } + /** + * Called when a player interacts with this entity + * @param player Player that is interacting with this entity + * @param interactReq Interact request protobuf data + */ + public void onInteract(Player player, GadgetInteractReq interactReq) { + + } + /** * Called when this entity is added to the world */ diff --git a/src/main/java/emu/grasscutter/game/entity/gadget/GadgetChest.java b/src/main/java/emu/grasscutter/game/entity/gadget/GadgetChest.java index 02da258fc..1fb146240 100644 --- a/src/main/java/emu/grasscutter/game/entity/gadget/GadgetChest.java +++ b/src/main/java/emu/grasscutter/game/entity/gadget/GadgetChest.java @@ -3,6 +3,7 @@ package emu.grasscutter.game.entity.gadget; import emu.grasscutter.Grasscutter; import emu.grasscutter.game.entity.EntityGadget; import emu.grasscutter.game.player.Player; +import emu.grasscutter.game.props.LifeState; import emu.grasscutter.net.proto.BossChestInfoOuterClass.BossChestInfo; import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.InterOpTypeOuterClass.InterOpType; @@ -11,6 +12,7 @@ import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType; import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo; import emu.grasscutter.scripts.constants.ScriptGadgetState; import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp; +import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify; public class GadgetChest extends GadgetContent { @@ -31,14 +33,13 @@ public class GadgetChest extends GadgetContent { return false; }else{ var success = handler.onInteract(this, player); - if (!success){ + if (!success) { return false; } getGadget().updateState(ScriptGadgetState.ChestOpened); player.sendPacket(new PacketGadgetInteractRsp(this.getGadget(), InteractTypeOuterClass.InteractType.INTERACT_TYPE_OPEN_CHEST)); - // let the chest disappear - getGadget().die(); + return true; } } diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index 60a156465..013f96c9d 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -995,52 +995,14 @@ public class Player { return this.getMailHandler().replaceMailByIndex(index, message); } - - public void interactWith(int gadgetEntityId, GadgetInteractReq opType) { - GameEntity entity = getScene().getEntityById(gadgetEntityId); - if (entity == null) { + public void interactWith(int gadgetEntityId, GadgetInteractReq interactReq) { + GameEntity target = getScene().getEntityById(gadgetEntityId); + + if (target == null) { return; } - - // Handle - if (entity instanceof EntityItem drop) { - // Pick item - if (!drop.isShare()) // check drop owner to avoid someone picked up item in others' world - { - int dropOwner = (int)(drop.getGuid() >> 32); - if (dropOwner != getUid()) { - return; - } - } - entity.getScene().removeEntity(entity); - GameItem item = new GameItem(drop.getItemData(), drop.getCount()); - // Add to inventory - boolean success = getInventory().addItem(item, ActionReason.SubfieldDrop); - if (success) { - if (!drop.isShare()) { // not shared drop - this.sendPacket(new PacketGadgetInteractRsp(drop, InteractType.INTERACT_TYPE_PICK_ITEM)); - }else{ - this.getScene().broadcastPacket(new PacketGadgetInteractRsp(drop, InteractType.INTERACT_TYPE_PICK_ITEM)); - } - } - } else if (entity instanceof EntityGadget gadget) { - if (gadget.getContent() == null) { - return; - } - - boolean shouldDelete = gadget.getContent().onInteract(this, opType); - - if (shouldDelete) { - entity.getScene().removeEntity(entity, VisionType.VISION_TYPE_REMOVE); - } - } else if (entity instanceof EntityMonster monster) { - insectCaptureManager.arrestSmallCreature(monster); - } else if (entity instanceof EntityVehicle vehicle) {// try to arrest it, example: glowworm - insectCaptureManager.arrestSmallCreature(vehicle); - } else { - // Delete directly - entity.getScene().removeEntity(entity); - } + + target.onInteract(this, interactReq); } public void onPause() { diff --git a/src/main/java/emu/grasscutter/game/world/Scene.java b/src/main/java/emu/grasscutter/game/world/Scene.java index 85a571293..d13bc3ef9 100644 --- a/src/main/java/emu/grasscutter/game/world/Scene.java +++ b/src/main/java/emu/grasscutter/game/world/Scene.java @@ -379,19 +379,28 @@ public class Scene { // Sanity check target.damage(result.getDamage(), result.getAttackerId()); } + + public void killEntity(GameEntity target) { + killEntity(target, 0); + } public void killEntity(GameEntity target, int attackerId) { - GameEntity attacker = getEntityById(attackerId); - - //Check codex - if (attacker instanceof EntityClientGadget) { - var clientGadgetOwner = getEntityById(((EntityClientGadget) attacker).getOwnerEntityId()); - if(clientGadgetOwner instanceof EntityAvatar) { - ((EntityClientGadget) attacker).getOwner().getCodex().checkAnimal(target, CodexAnimalData.CodexAnimalUnlockCondition.CODEX_COUNT_TYPE_KILL); - } + GameEntity attacker = null; + + if (attackerId > 0) { + attacker = getEntityById(attackerId); } - else if (attacker instanceof EntityAvatar) { - ((EntityAvatar) attacker).getPlayer().getCodex().checkAnimal(target, CodexAnimalData.CodexAnimalUnlockCondition.CODEX_COUNT_TYPE_KILL); + + if (attacker != null) { + // Check codex + if (attacker instanceof EntityClientGadget gadgetAttacker) { + var clientGadgetOwner = getEntityById(gadgetAttacker.getOwnerEntityId()); + if (clientGadgetOwner instanceof EntityAvatar) { + ((EntityClientGadget) attacker).getOwner().getCodex().checkAnimal(target, CodexAnimalData.CodexAnimalUnlockCondition.CODEX_COUNT_TYPE_KILL); + } + } else if (attacker instanceof EntityAvatar avatarAttacker) { + avatarAttacker.getPlayer().getCodex().checkAnimal(target, CodexAnimalData.CodexAnimalUnlockCondition.CODEX_COUNT_TYPE_KILL); + } } // Packet @@ -402,6 +411,7 @@ public class Scene { getWorld().getServer().getDropSystem().callDrop((EntityMonster) target); } + // Remove entity from world this.removeEntity(target); // Death event