From 01481fd524ce0111f935cf975cce63bbbbc831f6 Mon Sep 17 00:00:00 2001
From: zhaodice <63996691+zhaodice@users.noreply.github.com>
Date: Fri, 3 Jun 2022 15:51:51 +0800
Subject: [PATCH] Arresting small creature support (#1150)

* Arresting small creature support

* add InsectCaptureManager

* use EnvAnimalGatherExcelConfigData.json

* Update InsectCaptureManager.java
---
 .../java/emu/grasscutter/data/GameData.java   |  6 ++-
 .../excels/EnvAnimalGatherConfigData.java     | 40 +++++++++++++++++
 .../game/managers/InsectCaptureManager.java   | 44 +++++++++++++++++++
 .../emu/grasscutter/game/player/Player.java   | 29 +++++++-----
 4 files changed, 106 insertions(+), 13 deletions(-)
 create mode 100644 src/main/java/emu/grasscutter/data/excels/EnvAnimalGatherConfigData.java
 create mode 100644 src/main/java/emu/grasscutter/game/managers/InsectCaptureManager.java

diff --git a/src/main/java/emu/grasscutter/data/GameData.java b/src/main/java/emu/grasscutter/data/GameData.java
index 9d38d08e..1a366378 100644
--- a/src/main/java/emu/grasscutter/data/GameData.java
+++ b/src/main/java/emu/grasscutter/data/GameData.java
@@ -51,7 +51,8 @@ public class GameData {
 	private static final Int2ObjectMap<WeaponPromoteData> weaponPromoteDataMap = new Int2ObjectOpenHashMap<>();
 	private static final Int2ObjectMap<WeaponCurveData> weaponCurveDataMap = new Int2ObjectOpenHashMap<>();
 	private static final Int2ObjectMap<EquipAffixData> equipAffixDataMap = new Int2ObjectOpenHashMap<>();
-	
+
+	private static final Int2ObjectMap<EnvAnimalGatherConfigData> envAnimalGatherConfigDataMap = new Int2ObjectOpenHashMap<>();
 	private static final Int2ObjectMap<MonsterData> monsterDataMap = new Int2ObjectOpenHashMap<>();
 	private static final Int2ObjectMap<NpcData> npcDataMap = new Int2ObjectOpenHashMap<>();
 	private static final Int2ObjectMap<GadgetData> gadgetDataMap = new Int2ObjectOpenHashMap<>();
@@ -240,6 +241,9 @@ public class GameData {
 	public static Int2ObjectMap<MonsterData> getMonsterDataMap() {
 		return monsterDataMap;
 	}
+	public static Int2ObjectMap<EnvAnimalGatherConfigData> getEnvAnimalGatherConfigDataMap() {
+		return envAnimalGatherConfigDataMap;
+	}
 
 	public static Int2ObjectMap<NpcData> getNpcDataMap() {
 		return npcDataMap;
diff --git a/src/main/java/emu/grasscutter/data/excels/EnvAnimalGatherConfigData.java b/src/main/java/emu/grasscutter/data/excels/EnvAnimalGatherConfigData.java
new file mode 100644
index 00000000..e99d681e
--- /dev/null
+++ b/src/main/java/emu/grasscutter/data/excels/EnvAnimalGatherConfigData.java
@@ -0,0 +1,40 @@
+package emu.grasscutter.data.excels;
+
+import java.util.List;
+
+import emu.grasscutter.data.GameResource;
+import emu.grasscutter.data.ResourceType;
+
+@ResourceType(name = "EnvAnimalGatherExcelConfigData.json", loadPriority = ResourceType.LoadPriority.LOW)
+public class EnvAnimalGatherConfigData extends GameResource {
+    private int animalId;
+    private String entityType;
+    private List<GatherItem> gatherItemId;
+    private String excludeWeathers;
+    private int aliveTime;
+    private int escapeTime;
+    private int escapeRadius;
+    @Override
+    public int getId() {
+        return animalId;
+    }
+    public int getAnimalId(){
+        return animalId;
+    }
+    public String getEntityType(){
+        return entityType;
+    }
+    public GatherItem gatherItem(){
+        return gatherItemId.get(0);
+    }
+    public static class GatherItem{
+        private int id;
+        private int count;
+        public int getId(){
+            return id;
+        }
+        public int getCount(){
+            return count;
+        }
+    }
+}
diff --git a/src/main/java/emu/grasscutter/game/managers/InsectCaptureManager.java b/src/main/java/emu/grasscutter/game/managers/InsectCaptureManager.java
new file mode 100644
index 00000000..9fe5623b
--- /dev/null
+++ b/src/main/java/emu/grasscutter/game/managers/InsectCaptureManager.java
@@ -0,0 +1,44 @@
+package emu.grasscutter.game.managers;
+
+import emu.grasscutter.Grasscutter;
+import emu.grasscutter.data.GameData;
+import emu.grasscutter.data.excels.EnvAnimalGatherConfigData;
+import emu.grasscutter.data.excels.ItemData;
+import emu.grasscutter.game.entity.EntityMonster;
+import emu.grasscutter.game.entity.EntityVehicle;
+import emu.grasscutter.game.entity.GameEntity;
+import emu.grasscutter.game.inventory.GameItem;
+import emu.grasscutter.game.player.Player;
+import emu.grasscutter.game.props.ActionReason;
+import emu.grasscutter.net.proto.VisionTypeOuterClass;
+
+public record InsectCaptureManager(Player player) {
+    public void arrestSmallCreature(GameEntity entity) {
+        //System.out.println("arrestSmallCreature!");
+        EnvAnimalGatherConfigData gather;
+        int thingId;
+        if (entity instanceof EntityMonster monster) {
+            thingId = monster.getMonsterData().getId();
+            gather = GameData.getEnvAnimalGatherConfigDataMap().get(thingId);
+        } else if (entity instanceof EntityVehicle gadget) {
+            thingId = gadget.getGadgetId();
+            gather = GameData.getEnvAnimalGatherConfigDataMap().get(thingId);
+        } else {
+            return;
+        }
+        if (gather == null) {
+            Grasscutter.getLogger().warn("monster/gather(id={}) couldn't be caught.", thingId);
+            return;
+        }
+        String type = gather.getEntityType();
+        if ((type.equals("Monster") && entity instanceof EntityMonster) || (type.equals("Gadget") && entity instanceof EntityVehicle)) {
+            EnvAnimalGatherConfigData.GatherItem gatherItem = gather.gatherItem();
+            ItemData data = GameData.getItemDataMap().get(gatherItem.getId());
+            GameItem item = new GameItem(data, gatherItem.getCount());
+            player.getInventory().addItem(item, ActionReason.SubfieldDrop);
+            entity.getScene().removeEntity(entity, VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE);
+        } else {
+            Grasscutter.getLogger().warn("monster/gather(id={}) has a wrong type.", thingId);
+        }
+    }
+}
diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java
index 1a1b03b9..d2d86546 100644
--- a/src/main/java/emu/grasscutter/game/player/Player.java
+++ b/src/main/java/emu/grasscutter/game/player/Player.java
@@ -11,6 +11,8 @@ import emu.grasscutter.game.ability.AbilityManager;
 import emu.grasscutter.game.avatar.Avatar;
 import emu.grasscutter.game.avatar.AvatarProfileData;
 import emu.grasscutter.game.avatar.AvatarStorage;
+import emu.grasscutter.game.entity.EntityMonster;
+import emu.grasscutter.game.entity.EntityVehicle;
 import emu.grasscutter.game.managers.DeforestationManager.DeforestationManager;
 import emu.grasscutter.game.entity.EntityGadget;
 import emu.grasscutter.game.entity.EntityItem;
@@ -23,6 +25,7 @@ import emu.grasscutter.game.inventory.GameItem;
 import emu.grasscutter.game.inventory.Inventory;
 import emu.grasscutter.game.mail.Mail;
 import emu.grasscutter.game.mail.MailHandler;
+import emu.grasscutter.game.managers.InsectCaptureManager;
 import emu.grasscutter.game.managers.StaminaManager.StaminaManager;
 import emu.grasscutter.game.managers.SotSManager;
 import emu.grasscutter.game.managers.EnergyManager.EnergyManager;
@@ -47,6 +50,7 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
 import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
 import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
 import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
+
 import emu.grasscutter.server.event.player.PlayerJoinEvent;
 import emu.grasscutter.server.event.player.PlayerQuitEvent;
 import emu.grasscutter.server.game.GameServer;
@@ -105,6 +109,7 @@ public class Player {
 	@Transient private QuestManager questManager;
 	
 	@Transient private SotSManager sotsManager;
+	@Transient private InsectCaptureManager insectCaptureManager;
 
 	private TeamManager teamManager;
 
@@ -161,6 +166,7 @@ public class Player {
 		this.towerManager = new TowerManager(this);
 		this.abilityManager = new AbilityManager(this);
 		this.deforestationManager = new DeforestationManager(this);
+		this.insectCaptureManager = new InsectCaptureManager(this);
 
 		this.setQuestManager(new QuestManager(this));
 		this.pos = new Position();
@@ -907,47 +913,46 @@ public class Player {
 	
 	public void interactWith(int gadgetEntityId) {
 		GameEntity entity = getScene().getEntityById(gadgetEntityId);
-
 		if (entity == null) {
 			return;
 		}
 
 		// Handle
-		if (entity instanceof EntityItem) {
+		if (entity instanceof EntityItem drop) {
 			// Pick item
-			EntityItem drop = (EntityItem) entity;
 			if (!drop.isShare()) // check drop owner to avoid someone picked up item in others' world
 			{
 				int dropOwner = (int)(drop.getGuid() >> 32);
-				if (dropOwner != getUid())
+				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
+				if (!drop.isShare()) { // not shared drop
 					this.sendPacket(new PacketGadgetInteractRsp(drop, InteractType.INTERACT_TYPE_PICK_ITEM));
-				else
+				}else{
 					this.getScene().broadcastPacket(new PacketGadgetInteractRsp(drop, InteractType.INTERACT_TYPE_PICK_ITEM));
+				}
 			}
-		} else if (entity instanceof EntityGadget) {
-			EntityGadget gadget = (EntityGadget) entity;
-			
+		} else if (entity instanceof EntityGadget gadget) {
 			if (gadget.getGadgetData().getType() == EntityType.RewardStatue) {
 				if (scene.getChallenge() != null) {
 					scene.getChallenge().getStatueDrops(this);
 				}
-				
 				this.sendPacket(new PacketGadgetInteractRsp(gadget, InteractType.INTERACT_TYPE_OPEN_STATUE));
 			}
+		} 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);
 		}
-
-		return;
 	}
 
 	public void onPause() {
-- 
GitLab