Unverified Commit bf8ee323 authored by hamusuke's avatar hamusuke Committed by GitHub
Browse files

fix: albedo elevator doesn't work (#1845)

* Packet preparation

* elevator creation

* Make elevator work, scene time, entity removed event.

* Avoid referencing certain character name.
parent f801fe03
package emu.grasscutter.game.entity;
import emu.grasscutter.game.entity.platform.EntitySolarIsotomaElevatorPlatform;
import emu.grasscutter.game.entity.platform.EntityPlatform;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.EvtCreateGadgetNotifyOuterClass;
import lombok.Getter;
public class EntitySolarIsotomaClientGadget extends EntityClientGadget {
public static final int GADGET_ID = 41038001;
public static final int ELEVATOR_GADGET_ID = 41038002;
@Getter private EntityPlatform platformGadget;
public EntitySolarIsotomaClientGadget(Scene scene, Player player, EvtCreateGadgetNotifyOuterClass.EvtCreateGadgetNotify notify) {
super(scene, player, notify);
}
@Override
public void onCreate() {
//Create solar isotoma elevator and send to all.
this.platformGadget = new EntitySolarIsotomaElevatorPlatform(this, getScene(), getOwner(), ELEVATOR_GADGET_ID, getPosition(), getRotation());
getScene().addEntity(this.platformGadget);
getOwner().getTeamManager().getGadgets().add(this.platformGadget);
}
@Override
public void onRemoved() {
//Remove solar isotoma elevator entity.
getScene().removeEntity(this.platformGadget);
getOwner().getTeamManager().getGadgets().remove(this.platformGadget);
}
}
......@@ -219,6 +219,10 @@ public abstract class GameEntity {
}
public void onRemoved() {
}
/**
* Called when this entity dies
* @param killerId Entity id of the entity that killed this entity
......
package emu.grasscutter.game.entity.platform;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.ConfigGadget;
import emu.grasscutter.data.excels.GadgetData;
import emu.grasscutter.game.entity.EntityBaseGadget;
import emu.grasscutter.game.entity.EntityClientGadget;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
import lombok.Getter;
import lombok.Setter;
import javax.annotation.Nullable;
public class EntityPlatform extends EntityBaseGadget {
@Getter
private final Player owner;
private final int gadgetId;
@Getter
private final EntityClientGadget gadget;
private final Int2FloatMap fightProp;
private final Position pos;
private final Position rot;
@Nullable
@Getter
private ConfigGadget configGadget;
@Getter
private final MovingPlatformTypeOuterClass.MovingPlatformType movingPlatformType;
@Getter
@Setter
private boolean isStarted;
@Getter
@Setter
private boolean isActive;
public EntityPlatform(EntityClientGadget gadget, Scene scene, Player player, int gadgetId, Position pos, Position rot, MovingPlatformTypeOuterClass.MovingPlatformType movingPlatformType) {
super(scene);
this.gadget = gadget;
this.owner = player;
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
this.fightProp = new Int2FloatOpenHashMap();
this.pos = new Position(pos);
this.rot = new Position(rot);
this.movingPlatformType = movingPlatformType;
this.gadgetId = gadgetId;
GadgetData data = GameData.getGadgetDataMap().get(gadgetId);
if (data != null && data.getJsonName() != null) {
this.configGadget = GameData.getGadgetConfigData().get(data.getJsonName());
}
fillFightProps(configGadget);
}
@Override
public int getGadgetId() {
return gadgetId;
}
@Override
public Int2FloatMap getFightProperties() {
return fightProp;
}
@Override
public Position getPosition() {
return pos;
}
@Override
public Position getRotation() {
return rot;
}
@Override
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
var platform = PlatformInfoOuterClass.PlatformInfo.newBuilder()
.setMovingPlatformType(movingPlatformType)
.build();
var gadgetInfo = SceneGadgetInfoOuterClass.SceneGadgetInfo.newBuilder()
.setGadgetId(getGadgetId())
.setAuthorityPeerId(getOwner().getPeerId())
.setPlatform(platform);
var entityInfo = SceneEntityInfoOuterClass.SceneEntityInfo.newBuilder()
.setEntityId(getId())
.setEntityType(ProtEntityTypeOuterClass.ProtEntityType.PROT_ENTITY_TYPE_GADGET)
.setGadget(gadgetInfo)
.setLifeState(1);
for (Int2FloatMap.Entry entry : getFightProperties().int2FloatEntrySet()) {
if (entry.getIntKey() == 0) {
continue;
}
FightPropPairOuterClass.FightPropPair fightProp = FightPropPairOuterClass.FightPropPair.newBuilder().setPropType(entry.getIntKey()).setPropValue(entry.getFloatValue()).build();
entityInfo.addFightPropList(fightProp);
}
return entityInfo.build();
}
public PlatformInfoOuterClass.PlatformInfo onStartRoute() {
return PlatformInfoOuterClass.PlatformInfo.newBuilder()
.setStartSceneTime(getScene().getSceneTime())
.setIsStarted(true)
.setPosOffset(getPosition().toProto())
.setMovingPlatformType(getMovingPlatformType())
.setIsActive(true)
.build();
}
public PlatformInfoOuterClass.PlatformInfo onStopRoute() {
var sceneTime = getScene().getSceneTime();
return PlatformInfoOuterClass.PlatformInfo.newBuilder()
.setStartSceneTime(sceneTime)
.setStopSceneTime(sceneTime)
.setPosOffset(getPosition().toProto())
.setMovingPlatformType(getMovingPlatformType())
.build();
}
}
package emu.grasscutter.game.entity.platform;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.ConfigGadget;
import emu.grasscutter.game.entity.EntitySolarIsotomaClientGadget;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.server.packet.send.PacketSceneTimeNotify;
import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper;
public class EntitySolarIsotomaElevatorPlatform extends EntityPlatform {
public EntitySolarIsotomaElevatorPlatform(EntitySolarIsotomaClientGadget isotoma, Scene scene, Player player, int gadgetId, Position pos, Position rot) {
super(isotoma, scene, player, gadgetId, pos, rot, MovingPlatformTypeOuterClass.MovingPlatformType.MOVING_PLATFORM_TYPE_ABILITY);
}
@Override
protected void fillFightProps(ConfigGadget configGadget) {
if (configGadget == null || configGadget.getCombat() == null) {
return;
}
var combatData = configGadget.getCombat();
var combatProperties = combatData.getProperty();
if (combatProperties.isUseCreatorProperty()) {
//If useCreatorProperty == true, use owner's property;
GameEntity ownerAvatar = getScene().getEntityById(getGadget().getOwnerEntityId());
if (ownerAvatar != null) {
getFightProperties().putAll(ownerAvatar.getFightProperties());
return;
} else {
Grasscutter.getLogger().warn("Why gadget owner is null?");
}
}
super.fillFightProps(configGadget);
}
@Override
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
var gadget = SceneGadgetInfoOuterClass.SceneGadgetInfo.newBuilder()
.setGadgetId(getGadgetId())
.setOwnerEntityId(getGadget().getId())
.setAuthorityPeerId(getOwner().getPeerId())
.setIsEnableInteract(true)
.setAbilityGadget(AbilityGadgetInfoOuterClass.AbilityGadgetInfo.newBuilder()
.setCampId(getGadget().getCampId())
.setCampTargetType(getGadget().getCampType())
.setTargetEntityId(getGadget().getId())
.build())
.setPlatform(PlatformInfoOuterClass.PlatformInfo.newBuilder()
.setStartRot(MathQuaternionOuterClass.MathQuaternion.newBuilder()
.setW(1.0F)
.build())
.setPosOffset(getGadget().getPosition().toProto())
.setRotOffset(MathQuaternionOuterClass.MathQuaternion.newBuilder()
.setW(1.0F)
.build())
.setMovingPlatformType(MovingPlatformTypeOuterClass.MovingPlatformType.MOVING_PLATFORM_TYPE_ABILITY)
.build())
.build();
var authority = EntityAuthorityInfoOuterClass.EntityAuthorityInfo.newBuilder()
.setAiInfo(SceneEntityAiInfoOuterClass.SceneEntityAiInfo.newBuilder()
.setIsAiOpen(true)
.setBornPos(getGadget().getPosition().toProto()))
.setBornPos(getGadget().getPosition().toProto())
.build();
var info = SceneEntityInfoOuterClass.SceneEntityInfo.newBuilder()
.setEntityType(ProtEntityTypeOuterClass.ProtEntityType.PROT_ENTITY_TYPE_GADGET)
.setEntityId(getId())
.setMotionInfo(MotionInfoOuterClass.MotionInfo.newBuilder()
.setPos(getGadget().getPosition().toProto())
.setRot(getGadget().getRotation().toProto())
.build());
GameEntity entity = getScene().getEntityById(getGadget().getOwnerEntityId());
if (entity instanceof EntityAvatar avatar) {
info.addPropList(PropPairOuterClass.PropPair.newBuilder()
.setType(PlayerProperty.PROP_LEVEL.getId())
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, avatar.getAvatar().getLevel()))
.build());
} else {
Grasscutter.getLogger().warn("Why gadget owner doesn't exist?");
}
for (var entry : getFightProperties().int2FloatEntrySet()) {
if (entry.getIntKey() == 0) {
continue;
}
var fightProp = FightPropPairOuterClass.FightPropPair.newBuilder()
.setPropType(entry.getIntKey())
.setPropValue(entry.getFloatValue())
.build();
info.addFightPropList(fightProp);
}
info.setLifeState(1)
.setGadget(gadget)
.setEntityAuthorityInfo(authority);
return info.build();
}
@Override
public PlatformInfoOuterClass.PlatformInfo onStartRoute() {
setStarted(true);
setActive(true);
var sceneTime = getScene().getSceneTime();
getOwner().sendPacket(new PacketSceneTimeNotify(getOwner()));
return PlatformInfoOuterClass.PlatformInfo.newBuilder()
.setStartSceneTime(sceneTime + 300)
.setIsStarted(true)
.setPosOffset(getPosition().toProto())
.setRotOffset(MathQuaternionOuterClass.MathQuaternion.newBuilder()
.setW(1.0F)
.build())
.setMovingPlatformType(getMovingPlatformType())
.setIsActive(true)
.build();
}
@Override
public PlatformInfoOuterClass.PlatformInfo onStopRoute() {
setStarted(false);
setActive(false);
return PlatformInfoOuterClass.PlatformInfo.newBuilder()
.setStartSceneTime(getScene().getSceneTime())
.setStopSceneTime(getScene().getSceneTime())
.setPosOffset(getPosition().toProto())
.setRotOffset(MathQuaternionOuterClass.MathQuaternion.newBuilder()
.setW(1.0F)
.build())
.setMovingPlatformType(getMovingPlatformType())
.build();
}
}
......@@ -50,6 +50,7 @@ public class Scene {
@Getter @Setter private int autoCloseTime;
@Getter private int time;
private long startTime;
@Getter private SceneScriptManager scriptManager;
@Getter @Setter private WorldChallenge challenge;
......@@ -65,6 +66,7 @@ public class Scene {
this.entities = new ConcurrentHashMap<>();
this.time = 8 * 60;
this.startTime = System.currentTimeMillis();
this.prevScene = 3;
this.spawnedEntities = ConcurrentHashMap.newKeySet();
......@@ -103,6 +105,10 @@ public class Scene {
this.time = time % 1440;
}
public int getSceneTime() {
return (int) (System.currentTimeMillis() - this.startTime);
}
public void setDungeonData(DungeonData dungeonData) {
if (dungeonData == null || this.dungeonData != null || this.getSceneType() != SceneType.SCENE_DUNGEON || dungeonData.getSceneId() != this.getId()) {
return;
......@@ -235,7 +241,11 @@ public class Scene {
}
private GameEntity removeEntityDirectly(GameEntity entity) {
return getEntities().remove(entity.getId());
var removed = getEntities().remove(entity.getId());
if (removed != null) {
removed.onRemoved();//Call entity remove event
}
return removed;
}
public void removeEntity(GameEntity entity) {
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.entity.EntitySolarIsotomaClientGadget;
import emu.grasscutter.game.entity.EntityClientGadget;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
......@@ -20,7 +21,17 @@ public class HandlerEvtCreateGadgetNotify extends PacketHandler {
}
// Create entity and summon in world
EntityClientGadget gadget = new EntityClientGadget(session.getPlayer().getScene(), session.getPlayer(), notify);
var gadgetId = notify.getConfigId();
EntityClientGadget gadget = switch (gadgetId) {
//Solar Isotoma.
case EntitySolarIsotomaClientGadget.GADGET_ID ->
new EntitySolarIsotomaClientGadget(session.getPlayer().getScene(), session.getPlayer(), notify);
//Default.
default ->
new EntityClientGadget(session.getPlayer().getScene(), session.getPlayer(), notify);
};
session.getPlayer().getScene().onPlayerCreateGadget(gadget);
}
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.entity.platform.EntityPlatform;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.PacketHeadOuterClass;
import emu.grasscutter.net.proto.UpdateAbilityCreatedMovingPlatformNotifyOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketPlatformStartRouteNotify;
import emu.grasscutter.server.packet.send.PacketPlatformStopRouteNotify;
@Opcodes(PacketOpcodes.UpdateAbilityCreatedMovingPlatformNotify)
public class HandlerUpdateAbilityCreatedMovingPlatformNotify extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var sequence = PacketHeadOuterClass.PacketHead.parseFrom(header).getClientSequenceId();
var notify = UpdateAbilityCreatedMovingPlatformNotifyOuterClass.UpdateAbilityCreatedMovingPlatformNotify.parseFrom(payload);
var entity = session.getPlayer().getScene().getEntityById(notify.getEntityId());
if (!(entity instanceof EntityPlatform)) {
return;
}
switch (notify.getOpType()) {
case OP_TYPE_ACTIVATE -> session.send(new PacketPlatformStartRouteNotify(sequence, (EntityPlatform) entity, session.getPlayer().getScene()));
case OP_TYPE_DEACTIVATE -> session.send(new PacketPlatformStopRouteNotify(sequence, (EntityPlatform) entity, session.getPlayer().getScene()));
}
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.entity.platform.EntityPlatform;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.PlatformStartRouteNotifyOuterClass;
public class PacketPlatformStartRouteNotify extends BasePacket {
public PacketPlatformStartRouteNotify(int clientSequence, EntityPlatform entity, Scene scene) {
super(PacketOpcodes.PlatformStartRouteNotify, clientSequence);
var notify = PlatformStartRouteNotifyOuterClass.PlatformStartRouteNotify.newBuilder()
.setEntityId(entity.getId())
.setSceneTime(scene.getSceneTime())
.setPlatform(entity.onStartRoute())
.build();
this.setData(notify);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.entity.platform.EntityPlatform;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.PlatformStopRouteNotifyOuterClass;
public class PacketPlatformStopRouteNotify extends BasePacket {
public PacketPlatformStopRouteNotify(int clientSequence, EntityPlatform entity, Scene scene) {
super(PacketOpcodes.PlatformStopRouteNotify, clientSequence);
var notify = PlatformStopRouteNotifyOuterClass.PlatformStopRouteNotify.newBuilder()
.setPlatform(entity.onStopRoute())
.setSceneTime(scene.getSceneTime())
.setEntityId(entity.getId())
.build();
this.setData(notify);
}
}
......@@ -12,7 +12,7 @@ public class PacketSceneTimeNotify extends BasePacket {
SceneTimeNotify proto = SceneTimeNotify.newBuilder()
.setSceneId(player.getSceneId())
.setSceneTime(0)
.setSceneTime(player.getScene().getSceneTime())
.build();
this.setData(proto);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment