From 69381f393d315cd6244b8c6da5f09476d161f02f Mon Sep 17 00:00:00 2001 From: lilmayofuksu Date: Fri, 29 Apr 2022 22:01:07 +0300 Subject: [PATCH] Limit the amount of vehicles that a player can spawn (#340) --- .../game/entity/EntityVehicle.java | 13 ++++++- .../packet/send/PacketVehicleInteractRsp.java | 38 ++++++++++++++++++- .../packet/send/PacketVehicleSpawnRsp.java | 25 +++++++++++- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java b/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java index c7609f89b..09f80e15b 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java @@ -18,24 +18,30 @@ 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.utils.Position; import emu.grasscutter.utils.ProtoHelper; import it.unimi.dsi.fastutil.ints.Int2FloatMap; import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; +import java.util.List; +import java.util.ArrayList; + public class EntityVehicle extends EntityBaseGadget { + private final Player owner; private final Int2FloatOpenHashMap fightProp; private final Position pos; private final Position rot; - private float curStamina; private final int pointId; private final int gadgetId; + private float curStamina; + private List vehicleMembers; + public EntityVehicle(Scene scene, Player player, int gadgetId, int pointId, Position pos, Position rot) { super(scene); this.owner = player; @@ -46,6 +52,7 @@ public class EntityVehicle extends EntityBaseGadget { this.gadgetId = gadgetId; this.pointId = pointId; this.curStamina = 240; + this.vehicleMembers = new ArrayList(); } @Override @@ -61,6 +68,8 @@ public class EntityVehicle extends EntityBaseGadget { public int getPointId() { return pointId; } + public List getVehicleMembers() { return vehicleMembers; } + @Override public Int2FloatOpenHashMap getFightProperties() { return fightProp; diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleInteractRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleInteractRsp.java index 73476e821..989aa3876 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleInteractRsp.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleInteractRsp.java @@ -1,6 +1,7 @@ package emu.grasscutter.server.packet.send; import emu.grasscutter.Grasscutter; +import emu.grasscutter.game.entity.EntityVehicle; import emu.grasscutter.game.player.Player; import emu.grasscutter.game.entity.GameEntity; @@ -17,16 +18,49 @@ public class PacketVehicleInteractRsp extends BasePacket { VehicleInteractRsp.Builder proto = VehicleInteractRsp.newBuilder(); GameEntity vehicle = player.getScene().getEntityById(entityId); - if(vehicle != null) { + + if(vehicle instanceof EntityVehicle) { proto.setEntityId(vehicle.getId()); - proto.setInteractType(interactType); VehicleMember vehicleMember = VehicleMember.newBuilder() .setUid(player.getUid()) .setAvatarGuid(player.getTeamManager().getCurrentCharacterGuid()) .build(); + proto.setInteractType(interactType); proto.setMember(vehicleMember); + + switch(interactType){ + case VEHICLE_INTERACT_IN -> { + ((EntityVehicle) vehicle).getVehicleMembers().add(vehicleMember); + } + case VEHICLE_INTERACT_OUT -> { + ((EntityVehicle) vehicle).getVehicleMembers().remove(vehicleMember); + } + default -> {} + } + } + this.setData(proto.build()); + } + + public PacketVehicleInteractRsp(EntityVehicle vehicle, VehicleMember vehicleMember, VehicleInteractType interactType) { + super(PacketOpcodes.VehicleInteractRsp); + VehicleInteractRsp.Builder proto = VehicleInteractRsp.newBuilder(); + + if(vehicle != null) { + proto.setEntityId(vehicle.getId()); + proto.setInteractType(interactType); + proto.setMember(vehicleMember); + + switch(interactType){ + case VEHICLE_INTERACT_IN -> { + vehicle.getVehicleMembers().add(vehicleMember); + } + case VEHICLE_INTERACT_OUT -> { + vehicle.getVehicleMembers().remove(vehicleMember); + } + default -> {} + } } this.setData(proto.build()); } diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleSpawnRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleSpawnRsp.java index 69b3d8e6f..fe8b2a1f1 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleSpawnRsp.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketVehicleSpawnRsp.java @@ -8,10 +8,16 @@ import emu.grasscutter.game.entity.GameEntity; import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.PacketOpcodes; + +import emu.grasscutter.net.proto.VehicleMemberOuterClass.VehicleMember; import emu.grasscutter.net.proto.VehicleSpawnRspOuterClass.VehicleSpawnRsp; import emu.grasscutter.utils.Position; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; + +import java.util.List; + + +import static emu.grasscutter.net.proto.VehicleInteractTypeOuterClass.VehicleInteractType.VEHICLE_INTERACT_OUT; public class PacketVehicleSpawnRsp extends BasePacket { @@ -19,6 +25,23 @@ public class PacketVehicleSpawnRsp extends BasePacket { super(PacketOpcodes.VehicleSpawnRsp); VehicleSpawnRsp.Builder proto = VehicleSpawnRsp.newBuilder(); + // Eject vehicle members and Kill previous vehicles if there are any + List previousVehicles = player.getScene().getEntities().values().stream() + .filter(entity -> entity instanceof EntityVehicle + && ((EntityVehicle) entity).getGadgetId() == vehicleId + && ((EntityVehicle) entity).getOwner().equals(player)) + .toList(); + + previousVehicles.stream().forEach(entity -> { + List vehicleMembers = ((EntityVehicle) entity).getVehicleMembers().stream().toList(); + + vehicleMembers.stream().forEach(vehicleMember -> { + player.getScene().broadcastPacket(new PacketVehicleInteractRsp(((EntityVehicle) entity), vehicleMember, VEHICLE_INTERACT_OUT)); + }); + + player.getScene().killEntity(entity, 0); + }); + EntityVehicle vehicle = new EntityVehicle(player.getScene(), player, vehicleId, pointId, pos, rot); switch (vehicleId) {