Files
Grasscutter/src/main/java/emu/grasscutter/game/entity/EntityItem.java
2023-06-04 04:29:25 +00:00

166 lines
6.9 KiB
Java

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.Position;
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.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;
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.helpers.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import lombok.Getter;
public class EntityItem extends EntityBaseGadget {
@Getter private final GameItem item;
@Getter private final long guid;
@Getter private final boolean share;
public EntityItem(Scene scene, Player player, ItemData itemData, Position pos, int count) {
this(scene, player, itemData, pos, count, true);
}
public EntityItem(
Scene scene, Player player, ItemData itemData, Position pos, Position rotation, int count) {
this(scene, player, itemData, pos, rotation, count, true);
}
public EntityItem(
Scene scene, Player player, ItemData itemData, Position pos, int count, boolean share) {
this(scene, player, itemData, pos, null, count, share);
}
// In official game, some drop items are shared to all players, and some other items are
// independent to all players
// For example, if you killed a monster in MP mode, all players could get drops but rarity and
// number of them are different
// but if you broke regional mine, when someone picked up the drop then it disappeared
public EntityItem(
Scene scene,
Player player,
ItemData itemData,
Position pos,
Position rotation,
int count,
boolean share) {
super(scene, pos, rotation);
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
this.guid =
player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid();
this.item = new GameItem(itemData, count);
this.share = share;
}
public ItemData getItemData() {
return this.getItem().getItemData();
}
public int getCount() {
return this.getItem().getCount();
}
@Override
public int getGadgetId() {
return this.getItemData().getGadgetId();
}
@Override
public Int2FloatMap getFightProperties() {
return null;
}
@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() {
EntityAuthorityInfo authority =
EntityAuthorityInfo.newBuilder()
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
.setAiInfo(
SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(Vector.newBuilder()))
.setBornPos(Vector.newBuilder())
.build();
SceneEntityInfo.Builder entityInfo =
SceneEntityInfo.newBuilder()
.setEntityId(getId())
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_GADGET)
.setMotionInfo(
MotionInfo.newBuilder()
.setPos(getPosition().toProto())
.setRot(getRotation().toProto())
.setSpeed(Vector.newBuilder()))
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
.setEntityClientData(EntityClientData.newBuilder())
.setEntityAuthorityInfo(authority)
.setLifeState(1);
PropPair pair =
PropPair.newBuilder()
.setType(PlayerProperty.PROP_LEVEL.getId())
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 1))
.build();
entityInfo.addPropList(pair);
SceneGadgetInfo.Builder gadgetInfo =
SceneGadgetInfo.newBuilder()
.setGadgetId(this.getItemData().getGadgetId())
.setTrifleItem(this.getItem().toProto())
.setBornType(GadgetBornType.GADGET_BORN_TYPE_IN_AIR)
.setAuthorityPeerId(this.getWorld().getHostPeerId())
.setIsEnableInteract(true);
entityInfo.setGadget(gadgetInfo);
return entityInfo.build();
}
@Override
public void initAbilities() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'initAbilities'");
}
}