mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-26 20:05:19 +00:00
Hunting and deforestation support. (#1083)
* add drops for animals wild pig,fishes,foxes,birds * append fox * Deforestation Support implement drop woods when attacking tree * Deforestation support (remove prints) implement drop woods when attacking tree * Deforestation support (remove prints) implement drop woods when attacking tree * add AutoRecycleHashMap Map's KEY is automatic expire if key long time no use (query or modify from HashMap) * use AutoRecycleHashMap in case of memory leak * fix bug * remove prints * static AutoRecycleHashMap * fix problems * Delete AutoRecycleHashMap.java * remove log * fix build * improve * remove unnecessary information Co-authored-by: Albedo <105265570+arub3do@users.noreply.github.com> Co-authored-by: Albedo <105265570+arub3do@users.noreply.github.com>
This commit is contained in:
parent
830ac793fe
commit
a95002fd40
@ -0,0 +1,91 @@
|
||||
package emu.grasscutter.game.managers.DeforestationManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.entity.EntityItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.HitTreeNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.VectorOuterClass;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
public class DeforestationManager {
|
||||
final static int RECORD_EXPIRED_SECONDS = 60*5; // 5 min
|
||||
final static int RECORD_MAX_TIMES = 3; // max number of wood
|
||||
final static int RECORD_MAX_TIMES_OTHER_HIT_TREE = 10; // if hit 10 times other trees, reset wood
|
||||
|
||||
@Transient private final Player player;
|
||||
@Transient private final ArrayList<HitTreeRecord> currentRecord;
|
||||
@Transient private final static HashMap<Integer, Integer> ColliderTypeToWoodItemID = new HashMap<>();
|
||||
static {
|
||||
/* define wood types which reflected to item id*/
|
||||
ColliderTypeToWoodItemID.put(1,101301);
|
||||
ColliderTypeToWoodItemID.put(2,101302);
|
||||
ColliderTypeToWoodItemID.put(3,101303);
|
||||
ColliderTypeToWoodItemID.put(4,101304);
|
||||
ColliderTypeToWoodItemID.put(5,101305);
|
||||
ColliderTypeToWoodItemID.put(6,101306);
|
||||
ColliderTypeToWoodItemID.put(7,101307);
|
||||
ColliderTypeToWoodItemID.put(8,101308);
|
||||
ColliderTypeToWoodItemID.put(9,101309);
|
||||
ColliderTypeToWoodItemID.put(10,101310);
|
||||
ColliderTypeToWoodItemID.put(11,101311);
|
||||
ColliderTypeToWoodItemID.put(12,101312);
|
||||
}
|
||||
public DeforestationManager(Player player){
|
||||
this.player = player;
|
||||
this.currentRecord = new ArrayList<>();
|
||||
}
|
||||
public void resetWood(){
|
||||
synchronized (currentRecord) {
|
||||
currentRecord.clear();
|
||||
}
|
||||
}
|
||||
public void onDeforestationInvoke(HitTreeNotifyOuterClass.HitTreeNotify hit){
|
||||
synchronized (currentRecord) {
|
||||
//Grasscutter.getLogger().info("onDeforestationInvoke! Wood records {}", currentRecord);
|
||||
VectorOuterClass.Vector hitPosition = hit.getHitPostion();
|
||||
int woodType = hit.getWoodType();
|
||||
if (ColliderTypeToWoodItemID.containsKey(woodType)) {// is a available wood type
|
||||
Scene scene = player.getScene();
|
||||
int itemId = ColliderTypeToWoodItemID.get(woodType);
|
||||
int positionHash = hitPosition.hashCode();
|
||||
HitTreeRecord record = searchRecord(positionHash);
|
||||
if (record == null) {
|
||||
record = new HitTreeRecord(positionHash);
|
||||
}else{
|
||||
currentRecord.remove(record);// move it to last position
|
||||
}
|
||||
currentRecord.add(record);
|
||||
if(currentRecord.size()>RECORD_MAX_TIMES_OTHER_HIT_TREE){
|
||||
currentRecord.remove(0);
|
||||
}
|
||||
if(record.record()) {
|
||||
EntityItem entity = new EntityItem(scene,
|
||||
null,
|
||||
GameData.getItemDataMap().get(itemId),
|
||||
new Position(hitPosition.getX(), hitPosition.getY(), hitPosition.getZ()),
|
||||
1,
|
||||
false);
|
||||
scene.addEntity(entity);
|
||||
}
|
||||
//record.record()=false : too many wood they have deforested, no more wood dropped!
|
||||
} else {
|
||||
Grasscutter.getLogger().warn("No wood type {} found.", woodType);
|
||||
}
|
||||
}
|
||||
// unknown wood type
|
||||
}
|
||||
private HitTreeRecord searchRecord(int id){
|
||||
for (HitTreeRecord record : currentRecord) {
|
||||
if (record.getUnique() == id) {
|
||||
return record;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package emu.grasscutter.game.managers.DeforestationManager;
|
||||
|
||||
|
||||
|
||||
public class HitTreeRecord {
|
||||
private final int unique;
|
||||
private short count; // hit this tree times
|
||||
private long time; // last available hitting time
|
||||
HitTreeRecord(int unique){
|
||||
this.count = 0;
|
||||
this.time = 0;
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset hit time
|
||||
*/
|
||||
private void resetTime(){
|
||||
this.time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* commit hit behavior
|
||||
*/
|
||||
public boolean record(){
|
||||
if (this.count < DeforestationManager.RECORD_MAX_TIMES) {
|
||||
this.count++;
|
||||
resetTime();
|
||||
return true;
|
||||
}
|
||||
// check expired
|
||||
boolean isWaiting = System.currentTimeMillis() - this.time < DeforestationManager.RECORD_EXPIRED_SECONDS * 1000L;
|
||||
if(isWaiting){
|
||||
return false;
|
||||
}else{
|
||||
this.count = 1;
|
||||
resetTime();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* get unique id
|
||||
*/
|
||||
public int getUnique(){
|
||||
return unique;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HitTreeRecord{" +
|
||||
"unique=" + unique +
|
||||
", count=" + count +
|
||||
", time=" + time +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ 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.managers.DeforestationManager.DeforestationManager;
|
||||
import emu.grasscutter.game.entity.EntityGadget;
|
||||
import emu.grasscutter.game.entity.EntityItem;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
@ -145,11 +146,11 @@ public class Player {
|
||||
@Transient private MapMarksManager mapMarksManager;
|
||||
@Transient private StaminaManager staminaManager;
|
||||
@Transient private EnergyManager energyManager;
|
||||
@Transient private DeforestationManager deforestationManager;
|
||||
|
||||
private long springLastUsed;
|
||||
private HashMap<String, MapMark> mapMarks;
|
||||
|
||||
|
||||
@Deprecated
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
|
||||
public Player() {
|
||||
@ -159,6 +160,8 @@ public class Player {
|
||||
this.mailHandler = new MailHandler(this);
|
||||
this.towerManager = new TowerManager(this);
|
||||
this.abilityManager = new AbilityManager(this);
|
||||
this.deforestationManager = new DeforestationManager(this);
|
||||
|
||||
this.setQuestManager(new QuestManager(this));
|
||||
this.pos = new Position();
|
||||
this.rotation = new Position();
|
||||
@ -227,6 +230,7 @@ public class Player {
|
||||
this.staminaManager = new StaminaManager(this);
|
||||
this.sotsManager = new SotSManager(this);
|
||||
this.energyManager = new EnergyManager(this);
|
||||
this.deforestationManager = new DeforestationManager(this);
|
||||
}
|
||||
|
||||
public int getUid() {
|
||||
@ -923,7 +927,6 @@ public class Player {
|
||||
// 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_PICK_ITEM));
|
||||
else
|
||||
@ -1109,6 +1112,10 @@ public class Player {
|
||||
return abilityManager;
|
||||
}
|
||||
|
||||
public DeforestationManager getDeforestationManager() {
|
||||
return deforestationManager;
|
||||
}
|
||||
|
||||
public HashMap<String, MapMark> getMapMarks() { return mapMarks; }
|
||||
|
||||
public void setMapMarks(HashMap<String, MapMark> newMarks) { mapMarks = newMarks; }
|
||||
@ -1294,6 +1301,9 @@ public class Player {
|
||||
|
||||
// Call quit event.
|
||||
PlayerQuitEvent event = new PlayerQuitEvent(this); event.call();
|
||||
|
||||
//reset wood
|
||||
getDeforestationManager().resetWood();
|
||||
}
|
||||
|
||||
public enum SceneLoadState {
|
||||
|
@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HitTreeNotifyOuterClass.HitTreeNotify;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
/**
|
||||
* Implement Deforestation Function
|
||||
*/
|
||||
@Opcodes(PacketOpcodes.HitTreeNotify)
|
||||
public class HandlerHitTreeNotify extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
HitTreeNotify hit = HitTreeNotify.parseFrom(payload);
|
||||
session.getPlayer().getDeforestationManager().onDeforestationInvoke(hit);
|
||||
}
|
||||
}
|
@ -1,4 +1,44 @@
|
||||
[
|
||||
{"monsterId":28040101,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28040102,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28040103,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28040104,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28040105,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28040106,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28040107,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28040108,"dropDataList":[{"itemId":100084,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020301,"dropDataList":[{"itemId":100061,"minCount":2,"maxCount":2,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020302,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020101,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020102,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020103,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020104,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020105,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020106,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020701,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020702,"dropDataList":[{"itemId":100061,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020303,"dropDataList":[{"itemId":100094,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28020304,"dropDataList":[{"itemId":100094,"minCount":2,"maxCount":3,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030401,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030402,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030403,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030404,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030405,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030406,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030407,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030408,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030409,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030301,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030302,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030303,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030304,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030305,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030306,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030307,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030308,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030309,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030310,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{"monsterId":28030311,"dropDataList":[{"itemId":100064,"minCount":1,"maxCount":1,"minWeight":0,"maxWeight":10000}]},
|
||||
{
|
||||
"monsterId": 21010101,
|
||||
"dropDataList": [
|
||||
|
Loading…
Reference in New Issue
Block a user