mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-18 18:05:05 +01:00
Big World Resources Collection Implement (#1368)
* init * init * init * revoke * fix error * mining support * mining support * Roks endurance support * Roks endurance support * Timed refresh * upgrade resource data * Timed refresh support * remove null gadget * Coordination * full synchronized * oh no, my math teacher will hit me! * synchronized onInteract * remove break; * supply re-spawn time , thanks to @wl23333 * Clean up and integrate collection spawns into SpawnDataEntries Co-authored-by: Melledy <52122272+Melledy@users.noreply.github.com>
This commit is contained in:
@@ -8,11 +8,13 @@ import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.LifeState;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.game.world.SpawnDataEntry;
|
||||
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.FightPropPairOuterClass.FightPropPair;
|
||||
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
||||
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
|
||||
@@ -27,6 +29,7 @@ import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||
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 lombok.ToString;
|
||||
|
||||
@@ -40,19 +43,24 @@ public class EntityGadget extends EntityBaseGadget {
|
||||
private int state;
|
||||
private int pointType;
|
||||
private GadgetContent content;
|
||||
private Int2FloatOpenHashMap fightProp;
|
||||
private SceneGadget metaGadget;
|
||||
|
||||
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
||||
|
||||
public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot) {
|
||||
super(scene);
|
||||
this.data = GameData.getGadgetDataMap().get(gadgetId);
|
||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
||||
this.gadgetId = gadgetId;
|
||||
this.pos = pos.clone();
|
||||
this.rot = new Position();
|
||||
this.rot = rot != null ? rot.clone() : new Position();
|
||||
}
|
||||
|
||||
public EntityGadget(Scene scene, int gadgetId, Position pos, GadgetContent content) {
|
||||
this(scene, gadgetId, pos);
|
||||
|
||||
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
||||
this(scene, gadgetId, pos, new Position());
|
||||
}
|
||||
|
||||
public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot, GadgetContent content) {
|
||||
this(scene, gadgetId, pos, rot);
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@@ -126,6 +134,7 @@ public class EntityGadget extends EntityBaseGadget {
|
||||
EntityType type = getGadgetData().getType();
|
||||
GadgetContent content = switch (type) {
|
||||
case GatherPoint -> new GadgetGatherPoint(this);
|
||||
case GatherObject -> new GadgetGatherObject(this);
|
||||
case Worktop -> new GadgetWorktop(this);
|
||||
case RewardStatue -> new GadgetRewardStatue(this);
|
||||
case Chest -> new GadgetChest(this);
|
||||
@@ -137,7 +146,8 @@ public class EntityGadget extends EntityBaseGadget {
|
||||
|
||||
@Override
|
||||
public Int2FloatOpenHashMap getFightProperties() {
|
||||
return null;
|
||||
if (this.fightProp == null) this.fightProp = new Int2FloatOpenHashMap();
|
||||
return this.fightProp;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -148,7 +158,10 @@ public class EntityGadget extends EntityBaseGadget {
|
||||
|
||||
@Override
|
||||
public void onDeath(int killerId) {
|
||||
if(getScene().getChallenge() != null){
|
||||
if (this.getSpawnEntry() != null) {
|
||||
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
|
||||
}
|
||||
if (getScene().getChallenge() != null) {
|
||||
getScene().getChallenge().onGadgetDeath(this);
|
||||
}
|
||||
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_GADGET_DIE, new ScriptArgs(this.getConfigId()));
|
||||
@@ -178,6 +191,11 @@ public class EntityGadget extends EntityBaseGadget {
|
||||
.build();
|
||||
entityInfo.addPropList(pair);
|
||||
|
||||
// We do not use the getter to null check because the getter will create a fight prop map if it is null
|
||||
if (this.fightProp != null) {
|
||||
this.addAllFightPropsToEntityInfo(entityInfo);
|
||||
}
|
||||
|
||||
SceneGadgetInfo.Builder gadgetInfo = SceneGadgetInfo.newBuilder()
|
||||
.setGadgetId(this.getGadgetId())
|
||||
.setGroupId(this.getGroupId())
|
||||
|
||||
@@ -8,12 +8,14 @@ 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.MotionInfoOuterClass.MotionInfo;
|
||||
import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
|
||||
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
@@ -124,6 +126,16 @@ public abstract class GameEntity {
|
||||
return getFightProperties().getOrDefault(prop.getId(), 0f);
|
||||
}
|
||||
|
||||
public void addAllFightPropsToEntityInfo(SceneEntityInfo.Builder entityInfo) {
|
||||
for (Int2FloatMap.Entry entry : getFightProperties().int2FloatEntrySet()) {
|
||||
if (entry.getIntKey() == 0) {
|
||||
continue;
|
||||
}
|
||||
FightPropPair fightProp = FightPropPair.newBuilder().setPropType(entry.getIntKey()).setPropValue(entry.getFloatValue()).build();
|
||||
entityInfo.addFightPropList(fightProp);
|
||||
}
|
||||
}
|
||||
|
||||
public int getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@ package emu.grasscutter.game.entity.gadget;
|
||||
|
||||
import emu.grasscutter.game.entity.EntityGadget;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||
|
||||
public abstract class GadgetContent {
|
||||
private final EntityGadget gadget;
|
||||
|
||||
|
||||
public GadgetContent(EntityGadget gadget) {
|
||||
this.gadget = gadget;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package emu.grasscutter.game.entity.gadget;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.game.entity.EntityGadget;
|
||||
import emu.grasscutter.game.entity.EntityItem;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo;
|
||||
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
public class GadgetGatherObject extends GadgetContent {
|
||||
private int itemId;
|
||||
private boolean isForbidGuest;
|
||||
|
||||
public GadgetGatherObject(EntityGadget gadget) {
|
||||
super(gadget);
|
||||
|
||||
if (gadget.getSpawnEntry() != null) {
|
||||
this.itemId = gadget.getSpawnEntry().getGatherItemId();
|
||||
}
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return this.itemId;
|
||||
}
|
||||
|
||||
public boolean isForbidGuest() {
|
||||
return isForbidGuest;
|
||||
}
|
||||
|
||||
public boolean onInteract(Player player, GadgetInteractReq req) {
|
||||
// Sanity check
|
||||
ItemData itemData = GameData.getItemDataMap().get(getItemId());
|
||||
if (itemData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GameItem item = new GameItem(itemData, 1);
|
||||
player.getInventory().addItem(item, ActionReason.Gather);
|
||||
|
||||
getGadget().getScene().broadcastPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_TYPE_GATHER));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
||||
GatherGadgetInfo gatherGadgetInfo = GatherGadgetInfo.newBuilder()
|
||||
.setItemId(this.getItemId())
|
||||
.setIsForbidGuest(this.isForbidGuest())
|
||||
.build();
|
||||
|
||||
gadgetInfo.setGatherGadget(gatherGadgetInfo);
|
||||
}
|
||||
|
||||
public void dropItems(Player player) {
|
||||
Scene scene = getGadget().getScene();
|
||||
int times = Utils.randomRange(1,2);
|
||||
|
||||
for (int i = 0 ; i < times ; i++) {
|
||||
EntityItem item = new EntityItem(
|
||||
scene,
|
||||
player,
|
||||
GameData.getItemDataMap().get(itemId),
|
||||
new Position(
|
||||
getGadget().getPosition().getX() + (float)Utils.randomRange(1,5) / 5,
|
||||
getGadget().getPosition().getY() + 2f,
|
||||
getGadget().getPosition().getZ() + (float)Utils.randomRange(1,5) / 5
|
||||
),
|
||||
1,
|
||||
true);
|
||||
|
||||
scene.addEntity(item);
|
||||
}
|
||||
|
||||
scene.killEntity(this.getGadget(), player.getTeamManager().getCurrentAvatarEntity().getId());
|
||||
// Todo: add record
|
||||
}
|
||||
}
|
||||
@@ -3,31 +3,43 @@ package emu.grasscutter.game.entity.gadget;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.GatherData;
|
||||
import emu.grasscutter.game.entity.EntityGadget;
|
||||
import emu.grasscutter.game.entity.EntityItem;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo;
|
||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
public class GadgetGatherPoint extends GadgetContent {
|
||||
private GatherData gatherData;
|
||||
private int itemId;
|
||||
private boolean isForbidGuest;
|
||||
|
||||
public GadgetGatherPoint(EntityGadget gadget) {
|
||||
super(gadget);
|
||||
this.gatherData = GameData.getGatherDataMap().get(gadget.getPointType());
|
||||
}
|
||||
|
||||
public GatherData getGatherData() {
|
||||
return gatherData;
|
||||
|
||||
if (gadget.getSpawnEntry() != null) {
|
||||
this.itemId = gadget.getSpawnEntry().getGatherItemId();
|
||||
} else {
|
||||
GatherData gatherData = GameData.getGatherDataMap().get(gadget.getPointType());
|
||||
this.itemId = gatherData.getItemId();
|
||||
this.isForbidGuest = gatherData.isForbidGuest();
|
||||
}
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return getGatherData().getItemId();
|
||||
return this.itemId;
|
||||
}
|
||||
|
||||
public boolean isForbidGuest() {
|
||||
return isForbidGuest;
|
||||
}
|
||||
|
||||
public boolean onInteract(Player player, GadgetInteractReq req) {
|
||||
GameItem item = new GameItem(gatherData.getItemId(), 1);
|
||||
GameItem item = new GameItem(getItemId(), 1);
|
||||
|
||||
player.getInventory().addItem(item, ActionReason.Gather);
|
||||
|
||||
@@ -37,9 +49,33 @@ public class GadgetGatherPoint extends GadgetContent {
|
||||
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
||||
GatherGadgetInfo gatherGadgetInfo = GatherGadgetInfo.newBuilder()
|
||||
.setItemId(this.getItemId())
|
||||
.setIsForbidGuest(this.getGatherData().isForbidGuest())
|
||||
.setIsForbidGuest(this.isForbidGuest())
|
||||
.build();
|
||||
|
||||
gadgetInfo.setGatherGadget(gatherGadgetInfo);
|
||||
}
|
||||
|
||||
public void dropItems(Player player) {
|
||||
Scene scene = getGadget().getScene();
|
||||
int times = Utils.randomRange(1,2);
|
||||
|
||||
for (int i = 0 ; i < times ; i++) {
|
||||
EntityItem item = new EntityItem(
|
||||
scene,
|
||||
player,
|
||||
GameData.getItemDataMap().get(itemId),
|
||||
new Position(
|
||||
getGadget().getPosition().getX() + (float)Utils.randomRange(1,5) / 5,
|
||||
getGadget().getPosition().getY() + 2f,
|
||||
getGadget().getPosition().getZ() + (float)Utils.randomRange(1,5) / 5
|
||||
),
|
||||
1,
|
||||
true);
|
||||
|
||||
scene.addEntity(item);
|
||||
}
|
||||
|
||||
scene.killEntity(this.getGadget(), player.getTeamManager().getCurrentAvatarEntity().getId());
|
||||
// Todo: add record
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user