Commit bee654c6 authored by Melledy's avatar Melledy
Browse files

Implement support for multiple scenes in a world

parent eaba8bc1
...@@ -170,12 +170,12 @@ public class PlayerCommands { ...@@ -170,12 +170,12 @@ public class PlayerCommands {
float range = (5f + (.1f * count)); float range = (5f + (.1f * count));
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f).addZ((float) (Math.random() * range) - (range / 2)); Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f).addZ((float) (Math.random() * range) - (range / 2));
EntityItem entity = new EntityItem(player.getWorld(), player, itemData, pos, 1); EntityItem entity = new EntityItem(player.getScene(), player, itemData, pos, 1);
player.getWorld().addEntity(entity); player.getScene().addEntity(entity);
} }
} else { } else {
EntityItem entity = new EntityItem(player.getWorld(), player, itemData, player.getPos().clone().addY(3f), count); EntityItem entity = new EntityItem(player.getScene(), player, itemData, player.getPos().clone().addY(3f), count);
player.getWorld().addEntity(entity); player.getScene().addEntity(entity);
} }
} }
} }
...@@ -216,8 +216,8 @@ public class PlayerCommands { ...@@ -216,8 +216,8 @@ public class PlayerCommands {
float range = (5f + (.1f * count)); float range = (5f + (.1f * count));
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f).addZ((float) (Math.random() * range) - (range / 2)); Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f).addZ((float) (Math.random() * range) - (range / 2));
EntityMonster entity = new EntityMonster(player.getWorld(), monsterData, pos, level); EntityMonster entity = new EntityMonster(player.getScene(), monsterData, pos, level);
player.getWorld().addEntity(entity); player.getScene().addEntity(entity);
} }
} }
} }
...@@ -227,12 +227,12 @@ public class PlayerCommands { ...@@ -227,12 +227,12 @@ public class PlayerCommands {
@Override @Override
public void execute(GenshinPlayer player, String raw) { public void execute(GenshinPlayer player, String raw) {
List<GenshinEntity> toRemove = new LinkedList<>(); List<GenshinEntity> toRemove = new LinkedList<>();
for (GenshinEntity entity : player.getWorld().getEntities().values()) { for (GenshinEntity entity : player.getScene().getEntities().values()) {
if (entity instanceof EntityMonster) { if (entity instanceof EntityMonster) {
toRemove.add(entity); toRemove.add(entity);
} }
} }
toRemove.forEach(e -> player.getWorld().killEntity(e, 0)); toRemove.forEach(e -> player.getScene().killEntity(e, 0));
} }
} }
...@@ -286,7 +286,7 @@ public class PlayerCommands { ...@@ -286,7 +286,7 @@ public class PlayerCommands {
} }
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, hp); entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, hp);
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP)); entity.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
} }
} }
......
...@@ -83,6 +83,7 @@ public class GenshinPlayer { ...@@ -83,6 +83,7 @@ public class GenshinPlayer {
@Transient private long nextGuid = 0; @Transient private long nextGuid = 0;
@Transient private int peerId; @Transient private int peerId;
@Transient private World world; @Transient private World world;
@Transient private GenshinScene scene;
@Transient private GameSession session; @Transient private GameSession session;
@Transient private AvatarStorage avatars; @Transient private AvatarStorage avatars;
@Transient private Inventory inventory; @Transient private Inventory inventory;
...@@ -206,6 +207,14 @@ public class GenshinPlayer { ...@@ -206,6 +207,14 @@ public class GenshinPlayer {
this.world = world; this.world = world;
} }
public GenshinScene getScene() {
return scene;
}
public void setScene(GenshinScene scene) {
this.scene = scene;
}
public int getGmLevel() { public int getGmLevel() {
return 1; return 1;
} }
...@@ -560,14 +569,14 @@ public class GenshinPlayer { ...@@ -560,14 +569,14 @@ public class GenshinPlayer {
} }
public void interactWith(int gadgetEntityId) { public void interactWith(int gadgetEntityId) {
GenshinEntity entity = getWorld().getEntityById(gadgetEntityId); GenshinEntity entity = getScene().getEntityById(gadgetEntityId);
if (entity == null) { if (entity == null) {
return; return;
} }
// Delete // Delete
entity.getWorld().removeEntity(entity); entity.getScene().removeEntity(entity);
// Handle // Handle
if (entity instanceof EntityItem) { if (entity instanceof EntityItem) {
......
package emu.grasscutter.game;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.entity.EntityClientGadget;
import emu.grasscutter.game.entity.EntityGadget;
import emu.grasscutter.game.entity.GenshinEntity;
import emu.grasscutter.game.props.ClimateType;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState;
import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
import emu.grasscutter.server.packet.send.PacketSceneEntityDisappearNotify;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class GenshinScene {
private final World world;
private final List<GenshinPlayer> players;
private final Int2ObjectMap<GenshinEntity> entities;
private final int id;
private int time;
private ClimateType climate;
public GenshinScene(World world, int sceneId) {
this.world = world;
this.players = Collections.synchronizedList(new ArrayList<>());
this.entities = new Int2ObjectOpenHashMap<>();
this.id = sceneId;
this.time = 8 * 60;
this.climate = ClimateType.CLIMATE_SUNNY;
}
public int getId() {
return id;
}
public World getWorld() {
return world;
}
public List<GenshinPlayer> getPlayers() {
return players;
}
public int getPlayerCount() {
return this.getPlayers().size();
}
public Int2ObjectMap<GenshinEntity> getEntities() {
return entities;
}
public GenshinEntity getEntityById(int id) {
return this.entities.get(id);
}
public int getTime() {
return time;
}
public void changeTime(int time) {
this.time = time % 1440;
}
public ClimateType getClimate() {
return climate;
}
public void setClimate(ClimateType climate) {
this.climate = climate;
}
public boolean isInScene(GenshinEntity entity) {
return this.entities.containsKey(entity.getId());
}
public void addPlayer(GenshinPlayer player) {
// Check if player already in
if (getPlayers().contains(player)) {
return;
}
// Remove player from prev scene
if (player.getScene() != null) {
player.getScene().removePlayer(player);
}
// Add
getPlayers().add(player);
player.setSceneId(this.getId());
player.setScene(this);
this.setupPlayerAvatars(player);
}
public void removePlayer(GenshinPlayer player) {
getPlayers().remove(player);
player.setScene(null);
// Remove player avatars
this.removePlayerAvatars(player);
// Remove player gadgets
for (EntityGadget gadget : player.getTeamManager().getGadgets()) {
this.removeEntity(gadget);
}
}
private void setupPlayerAvatars(GenshinPlayer player) {
// Clear entities from old team
player.getTeamManager().getActiveTeam().clear();
// Add new entities for player
TeamInfo teamInfo = player.getTeamManager().getCurrentTeamInfo();
for (int avatarId : teamInfo.getAvatars()) {
EntityAvatar entity = new EntityAvatar(player.getScene(), player.getAvatars().getAvatarById(avatarId));
player.getTeamManager().getActiveTeam().add(entity);
}
// Limit character index in case its out of bounds
if (player.getTeamManager().getCurrentCharacterIndex() >= player.getTeamManager().getActiveTeam().size() || player.getTeamManager().getCurrentCharacterIndex() < 0) {
player.getTeamManager().setCurrentCharacterIndex(player.getTeamManager().getCurrentCharacterIndex() - 1);
}
}
private void removePlayerAvatars(GenshinPlayer player) {
Iterator<EntityAvatar> it = player.getTeamManager().getActiveTeam().iterator();
while (it.hasNext()) {
this.removeEntity(it.next(), VisionType.VisionRemove);
it.remove();
}
}
public void spawnPlayer(GenshinPlayer player) {
if (this.isInScene(player.getTeamManager().getCurrentAvatarEntity())) {
return;
}
if (player.getTeamManager().getCurrentAvatarEntity().getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
player.getTeamManager().getCurrentAvatarEntity().setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 1f);
}
this.addEntity(player.getTeamManager().getCurrentAvatarEntity());
}
private void addEntityDirectly(GenshinEntity entity) {
getEntities().put(entity.getId(), entity);
}
public synchronized void addEntity(GenshinEntity entity) {
this.addEntityDirectly(entity);
this.broadcastPacket(new PacketSceneEntityAppearNotify(entity));
}
public synchronized void addEntities(Collection<GenshinEntity> entities) {
for (GenshinEntity entity : entities) {
this.addEntityDirectly(entity);
}
this.broadcastPacket(new PacketSceneEntityAppearNotify(entities, VisionType.VisionBorn));
}
private GenshinEntity removeEntityDirectly(GenshinEntity entity) {
return getEntities().remove(entity.getId());
}
public void removeEntity(GenshinEntity entity) {
this.removeEntity(entity, VisionType.VisionDie);
}
public synchronized void removeEntity(GenshinEntity entity, VisionType visionType) {
GenshinEntity removed = this.removeEntityDirectly(entity);
if (removed != null) {
this.broadcastPacket(new PacketSceneEntityDisappearNotify(removed, visionType));
}
}
public synchronized void replaceEntity(EntityAvatar oldEntity, EntityAvatar newEntity) {
this.removeEntityDirectly(oldEntity);
this.addEntityDirectly(newEntity);
this.broadcastPacket(new PacketSceneEntityDisappearNotify(oldEntity, VisionType.VisionReplace));
this.broadcastPacket(new PacketSceneEntityAppearNotify(newEntity, VisionType.VisionReplace, oldEntity.getId()));
}
public void showOtherEntities(GenshinPlayer player) {
List<GenshinEntity> entities = new LinkedList<>();
GenshinEntity currentEntity = player.getTeamManager().getCurrentAvatarEntity();
for (GenshinEntity entity : this.getEntities().values()) {
if (entity == currentEntity) {
continue;
}
entities.add(entity);
}
player.sendPacket(new PacketSceneEntityAppearNotify(entities, VisionType.VisionMeet));
}
public void handleAttack(AttackResult result) {
//GenshinEntity attacker = getEntityById(result.getAttackerId());
GenshinEntity target = getEntityById(result.getDefenseId());
if (target == null) {
return;
}
// Godmode check
if (target instanceof EntityAvatar) {
if (((EntityAvatar) target).getPlayer().hasGodmode()) {
return;
}
}
// Lose hp
target.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -result.getDamage());
// Check if dead
boolean isDead = false;
if (target.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
target.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
isDead = true;
}
// Packets
this.broadcastPacket(new PacketEntityFightPropUpdateNotify(target, FightProperty.FIGHT_PROP_CUR_HP));
// Check if dead
if (isDead) {
this.killEntity(target, result.getAttackerId());
}
}
public void killEntity(GenshinEntity target, int attackerId) {
// Packet
this.broadcastPacket(new PacketLifeStateChangeNotify(attackerId, target, LifeState.LIFE_DEAD));
this.removeEntity(target);
// Death event
target.onDeath(attackerId);
}
// Gadgets
public void onPlayerCreateGadget(EntityClientGadget gadget) {
// Directly add
this.addEntityDirectly(gadget);
// Add to owner's gadget list
gadget.getOwner().getTeamManager().getGadgets().add(gadget);
// Optimization
if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == gadget.getOwner()) {
return;
}
this.broadcastPacketToOthers(gadget.getOwner(), new PacketSceneEntityAppearNotify(gadget));
}
public void onPlayerDestroyGadget(int entityId) {
GenshinEntity entity = getEntities().get(entityId);
if (entity == null || !(entity instanceof EntityClientGadget)) {
return;
}
// Get and remove entity
EntityClientGadget gadget = (EntityClientGadget) entity;
this.removeEntityDirectly(gadget);
// Remove from owner's gadget list
gadget.getOwner().getTeamManager().getGadgets().remove(gadget);
// Optimization
if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == gadget.getOwner()) {
return;
}
this.broadcastPacketToOthers(gadget.getOwner(), new PacketSceneEntityDisappearNotify(gadget, VisionType.VisionDie));
}
// Broadcasting
public void broadcastPacket(GenshinPacket packet) {
// Send to all players - might have to check if player has been sent data packets
for (GenshinPlayer player : this.getPlayers()) {
player.getSession().send(packet);
}
}
public void broadcastPacketToOthers(GenshinPlayer excludedPlayer, GenshinPacket packet) {
// Optimization
if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == excludedPlayer) {
return;
}
// Send to all players - might have to check if player has been sent data packets
for (GenshinPlayer player : this.getPlayers()) {
if (player == excludedPlayer) {
continue;
}
// Send
player.getSession().send(packet);
}
}
}
...@@ -46,12 +46,12 @@ public class InvokeHandler<T> { ...@@ -46,12 +46,12 @@ public class InvokeHandler<T> {
try { try {
if (entryListForwardAll.size() > 0) { if (entryListForwardAll.size() > 0) {
GenshinPacket packet = packetClass.getDeclaredConstructor(List.class).newInstance(this.entryListForwardAll); GenshinPacket packet = packetClass.getDeclaredConstructor(List.class).newInstance(this.entryListForwardAll);
player.getWorld().broadcastPacket(packet); player.getScene().broadcastPacket(packet);
this.entryListForwardAll.clear(); this.entryListForwardAll.clear();
} }
if (entryListForwardAllExceptCur.size() > 0) { if (entryListForwardAllExceptCur.size() > 0) {
GenshinPacket packet = packetClass.getDeclaredConstructor(List.class).newInstance(this.entryListForwardAllExceptCur); GenshinPacket packet = packetClass.getDeclaredConstructor(List.class).newInstance(this.entryListForwardAllExceptCur);
player.getWorld().broadcastPacketToOthers(player, packet); player.getScene().broadcastPacketToOthers(player, packet);
this.entryListForwardAllExceptCur.clear(); this.entryListForwardAllExceptCur.clear();
} }
if (entryListForwardHost.size() > 0) { if (entryListForwardHost.size() > 0) {
......
...@@ -158,7 +158,7 @@ public class TeamManager { ...@@ -158,7 +158,7 @@ public class TeamManager {
} }
public boolean isSpawned() { public boolean isSpawned() {
return getPlayer().getWorld() != null && getPlayer().getWorld().getEntities().containsKey(getCurrentAvatarEntity().getId()); return getPlayer().getWorld() != null && getPlayer().getScene().getEntities().containsKey(getCurrentAvatarEntity().getId());
} }
public int getMaxTeamSize() { public int getMaxTeamSize() {
...@@ -233,7 +233,7 @@ public class TeamManager { ...@@ -233,7 +233,7 @@ public class TeamManager {
prevSelectedAvatarIndex = i; prevSelectedAvatarIndex = i;
} }
} else { } else {
entity = new EntityAvatar(getPlayer().getWorld(), getPlayer().getAvatars().getAvatarById(avatarId)); entity = new EntityAvatar(getPlayer().getScene(), getPlayer().getAvatars().getAvatarById(avatarId));
} }
this.getActiveTeam().add(entity); this.getActiveTeam().add(entity);
...@@ -241,7 +241,7 @@ public class TeamManager { ...@@ -241,7 +241,7 @@ public class TeamManager {
// Unload removed entities // Unload removed entities
for (EntityAvatar entity : existingAvatars.values()) { for (EntityAvatar entity : existingAvatars.values()) {
getPlayer().getWorld().removeEntity(entity); getPlayer().getScene().removeEntity(entity);
entity.getAvatar().save(); entity.getAvatar().save();
} }
...@@ -256,7 +256,7 @@ public class TeamManager { ...@@ -256,7 +256,7 @@ public class TeamManager {
updateTeamResonances(); updateTeamResonances();
// Packets // Packets
getPlayer().getWorld().broadcastPacket(new PacketSceneTeamUpdateNotify(getPlayer())); getPlayer().getScene().broadcastPacket(new PacketSceneTeamUpdateNotify(getPlayer()));
// Run callback // Run callback
if (responsePacket != null) { if (responsePacket != null) {
...@@ -266,7 +266,7 @@ public class TeamManager { ...@@ -266,7 +266,7 @@ public class TeamManager {
// Check if character changed // Check if character changed
if (currentEntity != getCurrentAvatarEntity()) { if (currentEntity != getCurrentAvatarEntity()) {
// Remove and Add // Remove and Add
getWorld().replaceEntity(currentEntity, getCurrentAvatarEntity()); getPlayer().getScene().replaceEntity(currentEntity, getCurrentAvatarEntity());
} }
} }
...@@ -396,7 +396,7 @@ public class TeamManager { ...@@ -396,7 +396,7 @@ public class TeamManager {
oldEntity.setMotionState(MotionState.MotionStandby); oldEntity.setMotionState(MotionState.MotionStandby);
// Remove and Add // Remove and Add
getWorld().replaceEntity(oldEntity, newEntity); getPlayer().getScene().replaceEntity(oldEntity, newEntity);
getPlayer().sendPacket(new PacketChangeAvatarRsp(guid)); getPlayer().sendPacket(new PacketChangeAvatarRsp(guid));
} }
...@@ -426,7 +426,7 @@ public class TeamManager { ...@@ -426,7 +426,7 @@ public class TeamManager {
} else { } else {
// Set index and spawn replacement member // Set index and spawn replacement member
this.setCurrentCharacterIndex(replaceIndex); this.setCurrentCharacterIndex(replaceIndex);
getWorld().addEntity(replacement); getPlayer().getScene().addEntity(replacement);
} }
// Response packet // Response packet
......
...@@ -33,24 +33,21 @@ import emu.grasscutter.server.packet.send.PacketSyncScenePlayTeamEntityNotify; ...@@ -33,24 +33,21 @@ import emu.grasscutter.server.packet.send.PacketSyncScenePlayTeamEntityNotify;
import emu.grasscutter.server.packet.send.PacketSyncTeamEntityNotify; import emu.grasscutter.server.packet.send.PacketSyncTeamEntityNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerInfoNotify; import emu.grasscutter.server.packet.send.PacketWorldPlayerInfoNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify; import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class World implements Iterable<GenshinPlayer> { public class World implements Iterable<GenshinPlayer> {
private final GenshinPlayer owner; private final GenshinPlayer owner;
private final List<GenshinPlayer> players; private final List<GenshinPlayer> players;
private final Int2ObjectMap<GenshinScene> scenes;
private int levelEntityId; private int levelEntityId;
private int nextEntityId = 0; private int nextEntityId = 0;
private int nextPeerId = 0; private int nextPeerId = 0;
private final Int2ObjectMap<GenshinEntity> entities;
private int worldLevel; private int worldLevel;
private int sceneId;
private int time;
private ClimateType climate;
private boolean isMultiplayer; private boolean isMultiplayer;
private boolean isDungeon;
public World(GenshinPlayer player) { public World(GenshinPlayer player) {
this(player, false); this(player, false);
...@@ -59,11 +56,9 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -59,11 +56,9 @@ public class World implements Iterable<GenshinPlayer> {
public World(GenshinPlayer player, boolean isMultiplayer) { public World(GenshinPlayer player, boolean isMultiplayer) {
this.owner = player; this.owner = player;
this.players = Collections.synchronizedList(new ArrayList<>()); this.players = Collections.synchronizedList(new ArrayList<>());
this.entities = new Int2ObjectOpenHashMap<>(); this.scenes = new Int2ObjectOpenHashMap<>();
this.levelEntityId = getNextEntityId(EntityIdType.MPLEVEL); this.levelEntityId = getNextEntityId(EntityIdType.MPLEVEL);
this.sceneId = player.getSceneId();
this.time = 8 * 60;
this.climate = ClimateType.CLIMATE_SUNNY;
this.worldLevel = player.getWorldLevel(); this.worldLevel = player.getWorldLevel();
this.isMultiplayer = isMultiplayer; this.isMultiplayer = isMultiplayer;
} }
...@@ -87,22 +82,6 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -87,22 +82,6 @@ public class World implements Iterable<GenshinPlayer> {
return ++this.nextPeerId; return ++this.nextPeerId;
} }
public int getSceneId() {
return sceneId;
}
public void setSceneId(int sceneId) {
this.sceneId = sceneId;
}
public int getTime() {
return time;
}
public void changeTime(int time) {
this.time = time % 1440;
}
public int getWorldLevel() { public int getWorldLevel() {
return worldLevel; return worldLevel;
} }
...@@ -111,46 +90,30 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -111,46 +90,30 @@ public class World implements Iterable<GenshinPlayer> {
this.worldLevel = worldLevel; this.worldLevel = worldLevel;
} }
public ClimateType getClimate() {
return climate;
}
public void setClimate(ClimateType climate) {
this.climate = climate;
}
public List<GenshinPlayer> getPlayers() { public List<GenshinPlayer> getPlayers() {
return players; return players;
} }
public int getPlayerCount() { public Int2ObjectMap<GenshinScene> getScenes() {
return getPlayers().size(); return this.scenes;
} }
public Int2ObjectMap<GenshinEntity> getEntities() { public GenshinScene getSceneById(int sceneId) {
return this.entities; return getScenes().computeIfAbsent(sceneId, id -> new GenshinScene(this, id));
} }
public boolean isInWorld(GenshinEntity entity) { public int getPlayerCount() {
return this.entities.containsKey(entity.getId()); return getPlayers().size();
} }
public boolean isMultiplayer() { public boolean isMultiplayer() {
return isMultiplayer; return isMultiplayer;
} }
public boolean isDungeon() {
return isDungeon;
}
public int getNextEntityId(EntityIdType idType) { public int getNextEntityId(EntityIdType idType) {
return (idType.getId() << 24) + ++this.nextEntityId; return (idType.getId() << 24) + ++this.nextEntityId;
} }
public GenshinEntity getEntityById(int id) {
return this.entities.get(id);
}
public synchronized void addPlayer(GenshinPlayer player) { public synchronized void addPlayer(GenshinPlayer player) {
// Check if player already in // Check if player already in
if (getPlayers().contains(player)) { if (getPlayers().contains(player)) {
...@@ -165,13 +128,20 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -165,13 +128,20 @@ public class World implements Iterable<GenshinPlayer> {
// Register // Register
player.setWorld(this); player.setWorld(this);
getPlayers().add(player); getPlayers().add(player);
// Set player variables
player.setPeerId(this.getNextPeerId()); player.setPeerId(this.getNextPeerId());
player.getTeamManager().setEntityId(getNextEntityId(EntityIdType.TEAM)); player.getTeamManager().setEntityId(getNextEntityId(EntityIdType.TEAM));
// Setup team avatars // Copy main team to mp team
this.setupPlayerAvatars(player); if (this.isMultiplayer()) {
player.getTeamManager().getMpTeam().copyFrom(player.getTeamManager().getCurrentSinglePlayerTeamInfo(), player.getTeamManager().getMaxTeamSize());
}
// Add to scene
GenshinScene scene = this.getSceneById(player.getSceneId());
scene.addPlayer(player);
// Info packet for other players // Info packet for other players
if (this.getPlayers().size() > 1) { if (this.getPlayers().size() > 1) {
this.updatePlayerInfos(player); this.updatePlayerInfos(player);
...@@ -191,18 +161,15 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -191,18 +161,15 @@ public class World implements Iterable<GenshinPlayer> {
getPlayers().remove(player); getPlayers().remove(player);
player.setWorld(null); player.setWorld(null);
this.removePlayerAvatars(player); // Remove from scene
GenshinScene scene = this.getSceneById(player.getSceneId());
scene.removePlayer(player);
// Info packet for other players // Info packet for other players
if (this.getPlayers().size() > 0) { if (this.getPlayers().size() > 0) {
this.updatePlayerInfos(player); this.updatePlayerInfos(player);
} }
// Remove player gadgets
for (EntityGadget gadget : player.getTeamManager().getGadgets()) {
this.removeEntity(gadget);
}
// Disband world if host leaves // Disband world if host leaves
if (getHost() == player) { if (getHost() == player) {
List<GenshinPlayer> kicked = new ArrayList<>(this.getPlayers()); List<GenshinPlayer> kicked = new ArrayList<>(this.getPlayers());
...@@ -210,11 +177,24 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -210,11 +177,24 @@ public class World implements Iterable<GenshinPlayer> {
World world = new World(victim); World world = new World(victim);
world.addPlayer(victim); world.addPlayer(victim);
victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getWorld().getSceneId(), victim.getPos())); victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getSceneId(), victim.getPos()));
} }
} }
} }
public void transferPlayerToScene(GenshinPlayer player, int sceneId, Position pos) {
if (player.getScene() != null) {
player.getScene().removePlayer(player);
}
GenshinScene scene = this.getSceneById(sceneId);
scene.addPlayer(player);
player.getPos().set(pos);
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TransPoint, sceneId, pos));
}
private void updatePlayerInfos(GenshinPlayer paramPlayer) { private void updatePlayerInfos(GenshinPlayer paramPlayer) {
for (GenshinPlayer player : getPlayers()) { for (GenshinPlayer player : getPlayers()) {
// Dont send packets if player is loading in and filter out joining player // Dont send packets if player is loading in and filter out joining player
...@@ -239,185 +219,6 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -239,185 +219,6 @@ public class World implements Iterable<GenshinPlayer> {
} }
} }
private void addEntityDirectly(GenshinEntity entity) {
getEntities().put(entity.getId(), entity);
}
public synchronized void addEntity(GenshinEntity entity) {
this.addEntityDirectly(entity);
this.broadcastPacket(new PacketSceneEntityAppearNotify(entity));
}
public synchronized void addEntities(Collection<GenshinEntity> entities) {
for (GenshinEntity entity : entities) {
this.addEntityDirectly(entity);
}
this.broadcastPacket(new PacketSceneEntityAppearNotify(entities, VisionType.VisionBorn));
}
private GenshinEntity removeEntityDirectly(GenshinEntity entity) {
return getEntities().remove(entity.getId());
}
public void removeEntity(GenshinEntity entity) {
this.removeEntity(entity, VisionType.VisionDie);
}
public synchronized void removeEntity(GenshinEntity entity, VisionType visionType) {
GenshinEntity removed = this.removeEntityDirectly(entity);
if (removed != null) {
this.broadcastPacket(new PacketSceneEntityDisappearNotify(removed, visionType));
}
}
public synchronized void replaceEntity(EntityAvatar oldEntity, EntityAvatar newEntity) {
this.removeEntityDirectly(oldEntity);
this.addEntityDirectly(newEntity);
this.broadcastPacket(new PacketSceneEntityDisappearNotify(oldEntity, VisionType.VisionReplace));
this.broadcastPacket(new PacketSceneEntityAppearNotify(newEntity, VisionType.VisionReplace, oldEntity.getId()));
}
private void setupPlayerAvatars(GenshinPlayer player) {
// Copy main team to mp team
if (this.isMultiplayer()) {
player.getTeamManager().getMpTeam().copyFrom(player.getTeamManager().getCurrentSinglePlayerTeamInfo(), player.getTeamManager().getMaxTeamSize());
}
// Clear entities from old team
player.getTeamManager().getActiveTeam().clear();
// Add new entities for player
TeamInfo teamInfo = player.getTeamManager().getCurrentTeamInfo();
for (int avatarId : teamInfo.getAvatars()) {
EntityAvatar entity = new EntityAvatar(this, player.getAvatars().getAvatarById(avatarId));
player.getTeamManager().getActiveTeam().add(entity);
}
// Limit character index in case its out of bounds
if (player.getTeamManager().getCurrentCharacterIndex() >= player.getTeamManager().getActiveTeam().size() || player.getTeamManager().getCurrentCharacterIndex() < 0) {
player.getTeamManager().setCurrentCharacterIndex(player.getTeamManager().getCurrentCharacterIndex() - 1);
}
}
private void removePlayerAvatars(GenshinPlayer player) {
Iterator<EntityAvatar> it = player.getTeamManager().getActiveTeam().iterator();
while (it.hasNext()) {
this.removeEntity(it.next(), VisionType.VisionRemove);
it.remove();
}
}
public void spawnPlayer(GenshinPlayer player) {
if (isInWorld(player.getTeamManager().getCurrentAvatarEntity())) {
return;
}
if (player.getTeamManager().getCurrentAvatarEntity().getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
player.getTeamManager().getCurrentAvatarEntity().setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 1f);
}
this.addEntity(player.getTeamManager().getCurrentAvatarEntity());
}
public void showOtherEntities(GenshinPlayer player) {
List<GenshinEntity> entities = new LinkedList<>();
GenshinEntity currentEntity = player.getTeamManager().getCurrentAvatarEntity();
for (GenshinEntity entity : this.getEntities().values()) {
if (entity == currentEntity) {
continue;
}
entities.add(entity);
}
player.sendPacket(new PacketSceneEntityAppearNotify(entities, VisionType.VisionMeet));
}
public void handleAttack(AttackResult result) {
//GenshinEntity attacker = getEntityById(result.getAttackerId());
GenshinEntity target = getEntityById(result.getDefenseId());
if (target == null) {
return;
}
// Godmode check
if (target instanceof EntityAvatar) {
if (((EntityAvatar) target).getPlayer().hasGodmode()) {
return;
}
}
// Lose hp
target.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -result.getDamage());
// Check if dead
boolean isDead = false;
if (target.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
target.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
isDead = true;
}
// Packets
this.broadcastPacket(new PacketEntityFightPropUpdateNotify(target, FightProperty.FIGHT_PROP_CUR_HP));
// Check if dead
if (isDead) {
this.killEntity(target, result.getAttackerId());
}
}
public void killEntity(GenshinEntity target, int attackerId) {
// Packet
this.broadcastPacket(new PacketLifeStateChangeNotify(attackerId, target, LifeState.LIFE_DEAD));
this.removeEntity(target);
// Death event
target.onDeath(attackerId);
}
// Gadgets
public void onPlayerCreateGadget(EntityClientGadget gadget) {
// Directly add
this.addEntityDirectly(gadget);
// Add to owner's gadget list
gadget.getOwner().getTeamManager().getGadgets().add(gadget);
// Optimization
if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == gadget.getOwner()) {
return;
}
this.broadcastPacketToOthers(gadget.getOwner(), new PacketSceneEntityAppearNotify(gadget));
}
public void onPlayerDestroyGadget(int entityId) {
GenshinEntity entity = getEntities().get(entityId);
if (entity == null || !(entity instanceof EntityClientGadget)) {
return;
}
// Get and remove entity
EntityClientGadget gadget = (EntityClientGadget) entity;
this.removeEntityDirectly(gadget);
// Remove from owner's gadget list
gadget.getOwner().getTeamManager().getGadgets().remove(gadget);
// Optimization
if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == gadget.getOwner()) {
return;
}
this.broadcastPacketToOthers(gadget.getOwner(), new PacketSceneEntityDisappearNotify(gadget, VisionType.VisionDie));
}
// Broadcasting
public void broadcastPacket(GenshinPacket packet) { public void broadcastPacket(GenshinPacket packet) {
// Send to all players - might have to check if player has been sent data packets // Send to all players - might have to check if player has been sent data packets
for (GenshinPlayer player : this.getPlayers()) { for (GenshinPlayer player : this.getPlayers()) {
...@@ -425,21 +226,6 @@ public class World implements Iterable<GenshinPlayer> { ...@@ -425,21 +226,6 @@ public class World implements Iterable<GenshinPlayer> {
} }
} }
public void broadcastPacketToOthers(GenshinPlayer excludedPlayer, GenshinPacket packet) {
// Optimization
if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == excludedPlayer) {
return;
}
// Send to all players - might have to check if player has been sent data packets
for (GenshinPlayer player : this.getPlayers()) {
if (player == excludedPlayer) {
continue;
}
// Send
player.getSession().send(packet);
}
}
public void close() { public void close() {
} }
......
...@@ -122,7 +122,7 @@ public class AvatarStorage implements Iterable<GenshinAvatar> { ...@@ -122,7 +122,7 @@ public class AvatarStorage implements Iterable<GenshinAvatar> {
entity = new EntityAvatar(avatar); entity = new EntityAvatar(avatar);
getPlayer().sendPacket(new PacketAvatarChangeCostumeNotify(entity)); getPlayer().sendPacket(new PacketAvatarChangeCostumeNotify(entity));
} else { } else {
getPlayer().getWorld().broadcastPacket(new PacketAvatarChangeCostumeNotify(entity)); getPlayer().getScene().broadcastPacket(new PacketAvatarChangeCostumeNotify(entity));
} }
// Done // Done
......
...@@ -5,6 +5,7 @@ import emu.grasscutter.data.GenshinData; ...@@ -5,6 +5,7 @@ import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.AvatarData; import emu.grasscutter.data.def.AvatarData;
import emu.grasscutter.data.def.AvatarSkillDepotData; import emu.grasscutter.data.def.AvatarSkillDepotData;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World; import emu.grasscutter.game.World;
import emu.grasscutter.game.avatar.GenshinAvatar; import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.inventory.EquipType; import emu.grasscutter.game.inventory.EquipType;
...@@ -39,14 +40,14 @@ public class EntityAvatar extends GenshinEntity { ...@@ -39,14 +40,14 @@ public class EntityAvatar extends GenshinEntity {
private PlayerDieType killedType; private PlayerDieType killedType;
private int killedBy; private int killedBy;
public EntityAvatar(World world, GenshinAvatar avatar) { public EntityAvatar(GenshinScene scene, GenshinAvatar avatar) {
super(world); super(scene);
this.avatar = avatar; this.avatar = avatar;
this.id = world.getNextEntityId(EntityIdType.AVATAR); this.id = getScene().getWorld().getNextEntityId(EntityIdType.AVATAR);
GenshinItem weapon = this.getAvatar().getWeapon(); GenshinItem weapon = this.getAvatar().getWeapon();
if (weapon != null) { if (weapon != null) {
weapon.setWeaponEntityId(world.getNextEntityId(EntityIdType.WEAPON)); weapon.setWeaponEntityId(getScene().getWorld().getNextEntityId(EntityIdType.WEAPON));
} }
} }
...@@ -152,7 +153,7 @@ public class EntityAvatar extends GenshinEntity { ...@@ -152,7 +153,7 @@ public class EntityAvatar extends GenshinEntity {
.setLastMoveReliableSeq(this.getLastMoveReliableSeq()) .setLastMoveReliableSeq(this.getLastMoveReliableSeq())
.setLifeState(this.getLifeState().getValue()); .setLifeState(this.getLifeState().getValue());
if (this.getWorld() != null) { if (this.getScene() != null) {
entityInfo.setMotionInfo(this.getMotionInfo()); entityInfo.setMotionInfo(this.getMotionInfo());
} }
......
package emu.grasscutter.game.entity; package emu.grasscutter.game.entity;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World; import emu.grasscutter.game.World;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo; import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
...@@ -34,8 +35,8 @@ public class EntityClientGadget extends EntityGadget { ...@@ -34,8 +35,8 @@ public class EntityClientGadget extends EntityGadget {
private int targetEntityId; private int targetEntityId;
private boolean asyncLoad; private boolean asyncLoad;
public EntityClientGadget(World world, GenshinPlayer player, EvtCreateGadgetNotify notify) { public EntityClientGadget(GenshinScene scene, GenshinPlayer player, EvtCreateGadgetNotify notify) {
super(world); super(scene);
this.owner = player; this.owner = player;
this.id = notify.getEntityId(); this.id = notify.getEntityId();
this.pos = new Position(notify.getInitPos()); this.pos = new Position(notify.getInitPos());
......
package emu.grasscutter.game.entity; package emu.grasscutter.game.entity;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World; import emu.grasscutter.game.World;
public abstract class EntityGadget extends GenshinEntity { public abstract class EntityGadget extends GenshinEntity {
public EntityGadget(World world) { public EntityGadget(GenshinScene scene) {
super(world); super(scene);
} }
public abstract int getGadgetId(); public abstract int getGadgetId();
......
...@@ -2,6 +2,7 @@ package emu.grasscutter.game.entity; ...@@ -2,6 +2,7 @@ package emu.grasscutter.game.entity;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World; import emu.grasscutter.game.World;
import emu.grasscutter.game.inventory.GenshinItem; import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.props.EntityIdType; import emu.grasscutter.game.props.EntityIdType;
...@@ -30,9 +31,9 @@ public class EntityItem extends EntityGadget { ...@@ -30,9 +31,9 @@ public class EntityItem extends EntityGadget {
private final GenshinItem item; private final GenshinItem item;
private final long guid; private final long guid;
public EntityItem(World world, GenshinPlayer player, ItemData itemData, Position pos, int count) { public EntityItem(GenshinScene scene, GenshinPlayer player, ItemData itemData, Position pos, int count) {
super(world); super(scene);
this.id = world.getNextEntityId(EntityIdType.GADGET); this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
this.pos = new Position(pos); this.pos = new Position(pos);
this.rot = new Position(); this.rot = new Position();
this.guid = player.getNextGuid(); this.guid = player.getNextGuid();
......
...@@ -4,6 +4,7 @@ import emu.grasscutter.data.GenshinData; ...@@ -4,6 +4,7 @@ import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.common.PropGrowCurve; import emu.grasscutter.data.common.PropGrowCurve;
import emu.grasscutter.data.def.MonsterCurveData; import emu.grasscutter.data.def.MonsterCurveData;
import emu.grasscutter.data.def.MonsterData; import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World; import emu.grasscutter.game.World;
import emu.grasscutter.game.props.EntityIdType; import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
...@@ -36,9 +37,9 @@ public class EntityMonster extends GenshinEntity { ...@@ -36,9 +37,9 @@ public class EntityMonster extends GenshinEntity {
private final int level; private final int level;
private int weaponEntityId; private int weaponEntityId;
public EntityMonster(World world, MonsterData monsterData, Position pos, int level) { public EntityMonster(GenshinScene scene, MonsterData monsterData, Position pos, int level) {
super(world); super(scene);
this.id = world.getNextEntityId(EntityIdType.MONSTER); this.id = getWorld().getNextEntityId(EntityIdType.MONSTER);
this.monsterData = monsterData; this.monsterData = monsterData;
this.fightProp = new Int2FloatOpenHashMap(); this.fightProp = new Int2FloatOpenHashMap();
this.pos = new Position(pos); this.pos = new Position(pos);
...@@ -48,7 +49,7 @@ public class EntityMonster extends GenshinEntity { ...@@ -48,7 +49,7 @@ public class EntityMonster extends GenshinEntity {
// Monster weapon // Monster weapon
if (getMonsterWeaponId() > 0) { if (getMonsterWeaponId() > 0) {
this.weaponEntityId = world.getNextEntityId(EntityIdType.WEAPON); this.weaponEntityId = getWorld().getNextEntityId(EntityIdType.WEAPON);
} }
this.recalcStats(); this.recalcStats();
......
package emu.grasscutter.game.entity; package emu.grasscutter.game.entity;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World; import emu.grasscutter.game.World;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState; import emu.grasscutter.game.props.LifeState;
...@@ -12,23 +13,27 @@ import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; ...@@ -12,23 +13,27 @@ import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public abstract class GenshinEntity { public abstract class GenshinEntity {
protected int id; protected int id;
private final World world; private final GenshinScene scene;
private MotionState moveState; private MotionState moveState;
private int lastMoveSceneTimeMs; private int lastMoveSceneTimeMs;
private int lastMoveReliableSeq; private int lastMoveReliableSeq;
public GenshinEntity(World world) { public GenshinEntity(GenshinScene scene) {
this.world = world; this.scene = scene;
this.moveState = MotionState.MotionNone; this.moveState = MotionState.MotionNone;
} }
public int getId() { public int getId() {
return this.id; return this.id;
} }
public World getWorld() { public World getWorld() {
return world; return this.getScene().getWorld();
}
public GenshinScene getScene() {
return this.scene;
} }
public boolean isAlive() { public boolean isAlive() {
......
...@@ -35,10 +35,12 @@ public class MultiplayerManager { ...@@ -35,10 +35,12 @@ public class MultiplayerManager {
return; return;
} }
/*
if (target.getWorld().isDungeon()) { if (target.getWorld().isDungeon()) {
player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.SceneCannotEnter)); player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.SceneCannotEnter));
return; return;
} }
*/
// Get request // Get request
CoopRequest request = target.getCoopRequests().get(player.getId()); CoopRequest request = target.getCoopRequests().get(player.getId());
...@@ -90,14 +92,14 @@ public class MultiplayerManager { ...@@ -90,14 +92,14 @@ public class MultiplayerManager {
world.addPlayer(player); world.addPlayer(player);
// Rejoin packet // Rejoin packet
player.sendPacket(new PacketPlayerEnterSceneNotify(player, player, EnterType.EnterSelf, EnterReason.HostFromSingleToMp, player.getWorld().getSceneId(), player.getPos())); player.sendPacket(new PacketPlayerEnterSceneNotify(player, player, EnterType.EnterSelf, EnterReason.HostFromSingleToMp, player.getScene().getId(), player.getPos()));
} }
// Make requester join // Make requester join
player.getWorld().addPlayer(requester); player.getWorld().addPlayer(requester);
// Packet // Packet
requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, player, EnterType.EnterOther, EnterReason.TeamJoin, player.getWorld().getSceneId(), player.getPos())); requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, player, EnterType.EnterOther, EnterReason.TeamJoin, player.getScene().getId(), player.getPos()));
requester.getPos().set(player.getPos()); requester.getPos().set(player.getPos());
requester.getRotation().set(player.getRotation()); requester.getRotation().set(player.getRotation());
} }
...@@ -120,7 +122,7 @@ public class MultiplayerManager { ...@@ -120,7 +122,7 @@ public class MultiplayerManager {
world.addPlayer(player); world.addPlayer(player);
// Packet // Packet
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TeamBack, player.getWorld().getSceneId(), player.getPos())); player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TeamBack, player.getScene().getId(), player.getPos()));
return true; return true;
} }
...@@ -147,7 +149,7 @@ public class MultiplayerManager { ...@@ -147,7 +149,7 @@ public class MultiplayerManager {
World world = new World(victim); World world = new World(victim);
world.addPlayer(victim); world.addPlayer(victim);
victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getWorld().getSceneId(), victim.getPos())); victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getScene().getId(), victim.getPos()));
return true; return true;
} }
} }
...@@ -958,6 +958,7 @@ public class PacketOpcodes { ...@@ -958,6 +958,7 @@ public class PacketOpcodes {
public static final int SceneTimeNotify = 229; public static final int SceneTimeNotify = 229;
public static final int SceneTransToPointReq = 256; public static final int SceneTransToPointReq = 256;
public static final int SceneTransToPointRsp = 283; public static final int SceneTransToPointRsp = 283;
public static final int SceneUnlockInfoNotify = 3386;
public static final int SceneWeatherForcastReq = 3167; public static final int SceneWeatherForcastReq = 3167;
public static final int SceneWeatherForcastRsp = 3023; public static final int SceneWeatherForcastRsp = 3023;
public static final int SeaLampCoinNotify = 2028; public static final int SeaLampCoinNotify = 2028;
......
...@@ -14,8 +14,8 @@ public class HandlerChangeGameTimeReq extends PacketHandler { ...@@ -14,8 +14,8 @@ public class HandlerChangeGameTimeReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
ChangeGameTimeReq req = ChangeGameTimeReq.parseFrom(payload); ChangeGameTimeReq req = ChangeGameTimeReq.parseFrom(payload);
session.getPlayer().getWorld().changeTime(req.getGameTime()); session.getPlayer().getScene().changeTime(req.getGameTime());
session.getPlayer().sendPacket(new PacketChangeGameTimeRsp(session.getPlayer().getWorld())); session.getPlayer().sendPacket(new PacketChangeGameTimeRsp(session.getPlayer()));
} }
} }
...@@ -22,12 +22,12 @@ public class HandlerCombatInvocationsNotify extends PacketHandler { ...@@ -22,12 +22,12 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
case CombatEvtBeingHit: case CombatEvtBeingHit:
// Handle damage // Handle damage
EvtBeingHitInfo hitInfo = EvtBeingHitInfo.parseFrom(entry.getCombatData()); EvtBeingHitInfo hitInfo = EvtBeingHitInfo.parseFrom(entry.getCombatData());
session.getPlayer().getWorld().handleAttack(hitInfo.getAttackResult()); session.getPlayer().getScene().handleAttack(hitInfo.getAttackResult());
break; break;
case EntityMove: case EntityMove:
// Handle movement // Handle movement
EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData()); EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData());
GenshinEntity entity = session.getPlayer().getWorld().getEntityById(moveInfo.getEntityId()); GenshinEntity entity = session.getPlayer().getScene().getEntityById(moveInfo.getEntityId());
if (entity != null) { if (entity != null) {
entity.getPosition().set(moveInfo.getMotionInfo().getPos()); entity.getPosition().set(moveInfo.getMotionInfo().getPos());
entity.getRotation().set(moveInfo.getMotionInfo().getRot()); entity.getRotation().set(moveInfo.getMotionInfo().getRot());
......
...@@ -24,10 +24,10 @@ public class HandlerEnterSceneDoneReq extends PacketHandler { ...@@ -24,10 +24,10 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place
// Spawn player in world // Spawn player in world
session.getPlayer().getWorld().spawnPlayer(session.getPlayer()); session.getPlayer().getScene().spawnPlayer(session.getPlayer());
// Spawn other entites already in world // Spawn other entites already in world
session.getPlayer().getWorld().showOtherEntities(session.getPlayer()); session.getPlayer().getScene().showOtherEntities(session.getPlayer());
// Locations // Locations
session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld())); session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld()));
......
...@@ -15,7 +15,7 @@ public class HandlerEntityAiSyncNotify extends PacketHandler { ...@@ -15,7 +15,7 @@ public class HandlerEntityAiSyncNotify extends PacketHandler {
EntityAiSyncNotify notify = EntityAiSyncNotify.parseFrom(payload); EntityAiSyncNotify notify = EntityAiSyncNotify.parseFrom(payload);
if (notify.getLocalAvatarAlertedMonsterListCount() > 0) { if (notify.getLocalAvatarAlertedMonsterListCount() > 0) {
session.getPlayer().getWorld().broadcastPacket(new PacketEntityAiSyncNotify(notify)); session.getPlayer().getScene().broadcastPacket(new PacketEntityAiSyncNotify(notify));
} }
} }
......
...@@ -20,13 +20,13 @@ public class HandlerEvtCreateGadgetNotify extends PacketHandler { ...@@ -20,13 +20,13 @@ public class HandlerEvtCreateGadgetNotify extends PacketHandler {
} }
// Sanity check - dont add duplicate entities // Sanity check - dont add duplicate entities
if (session.getPlayer().getWorld().getEntityById(notify.getEntityId()) != null) { if (session.getPlayer().getScene().getEntityById(notify.getEntityId()) != null) {
return; return;
} }
// Create entity and summon in world // Create entity and summon in world
EntityClientGadget gadget = new EntityClientGadget(session.getPlayer().getWorld(), session.getPlayer(), notify); EntityClientGadget gadget = new EntityClientGadget(session.getPlayer().getScene(), session.getPlayer(), notify);
session.getPlayer().getWorld().onPlayerCreateGadget(gadget); session.getPlayer().getScene().onPlayerCreateGadget(gadget);
} }
} }
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