mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-18 18:05:05 +01:00
Fix double adding of avatar entities
This commit is contained in:
@@ -1,95 +1,95 @@
|
|||||||
package emu.grasscutter.game.player;
|
package emu.grasscutter.game.player;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam;
|
import emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class TeamInfo {
|
public final class TeamInfo {
|
||||||
private String name;
|
private String name;
|
||||||
private final List<Integer> avatars;
|
private final List<Integer> avatars;
|
||||||
|
|
||||||
public TeamInfo() {
|
public TeamInfo() {
|
||||||
this.name = "";
|
this.name = "";
|
||||||
this.avatars = new ArrayList<>(GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
this.avatars = new ArrayList<>(GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TeamInfo(List<Integer> avatars) {
|
public TeamInfo(List<Integer> avatars) {
|
||||||
this.name = "";
|
this.name = "";
|
||||||
this.avatars = avatars;
|
this.avatars = avatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getAvatars() {
|
public List<Integer> getAvatars() {
|
||||||
return avatars;
|
return avatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return avatars.size();
|
return avatars.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(Avatar avatar) {
|
public boolean contains(Avatar avatar) {
|
||||||
return getAvatars().contains(avatar.getAvatarId());
|
return getAvatars().contains(avatar.getAvatarId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addAvatar(Avatar avatar) {
|
public boolean addAvatar(Avatar avatar) {
|
||||||
if (contains(avatar)) {
|
if (contains(avatar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvatars().add(avatar.getAvatarId());
|
getAvatars().add(avatar.getAvatarId());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeAvatar(int slot) {
|
public boolean removeAvatar(int slot) {
|
||||||
if (size() <= 1) {
|
if (size() <= 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvatars().remove(slot);
|
getAvatars().remove(slot);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFrom(TeamInfo team) {
|
public void copyFrom(TeamInfo team) {
|
||||||
copyFrom(team, GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
copyFrom(team, GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFrom(TeamInfo team, int maxTeamSize) {
|
public void copyFrom(TeamInfo team, int maxTeamSize) {
|
||||||
// Clone avatar ids from team to copy from
|
// Clone avatar ids from team to copy from
|
||||||
List<Integer> avatarIds = new ArrayList<>(team.getAvatars());
|
List<Integer> avatarIds = new ArrayList<>(team.getAvatars());
|
||||||
|
|
||||||
// Clear current avatar list first
|
// Clear current avatar list first
|
||||||
this.getAvatars().clear();
|
this.getAvatars().clear();
|
||||||
|
|
||||||
// Copy from team
|
// Copy from team
|
||||||
int len = Math.min(avatarIds.size(), maxTeamSize);
|
int len = Math.min(avatarIds.size(), maxTeamSize);
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
int id = avatarIds.get(i);
|
int id = avatarIds.get(i);
|
||||||
this.getAvatars().add(id);
|
this.getAvatars().add(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarTeam toProto(Player player) {
|
public AvatarTeam toProto(Player player) {
|
||||||
AvatarTeam.Builder avatarTeam = AvatarTeam.newBuilder().setTeamName(this.getName());
|
AvatarTeam.Builder avatarTeam = AvatarTeam.newBuilder().setTeamName(this.getName());
|
||||||
|
|
||||||
for (int i = 0; i < this.getAvatars().size(); i++) {
|
for (int i = 0; i < this.getAvatars().size(); i++) {
|
||||||
Avatar avatar = player.getAvatars().getAvatarById(this.getAvatars().get(i));
|
Avatar avatar = player.getAvatars().getAvatarById(this.getAvatars().get(i));
|
||||||
avatarTeam.addAvatarGuidList(avatar.getGuid());
|
avatarTeam.addAvatarGuidList(avatar.getGuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
return avatarTeam.build();
|
return avatarTeam.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,30 @@ public final class TeamManager extends BasePlayerDataManager {
|
|||||||
return avatars;
|
return avatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the active team.
|
||||||
|
* If there are errors with the team, they can be fixed.
|
||||||
|
*
|
||||||
|
* @param fix If true, the team will be fixed.
|
||||||
|
* @return The active team.
|
||||||
|
*/
|
||||||
|
public List<EntityAvatar> getActiveTeam(boolean fix) {
|
||||||
|
if (!fix) return this.getActiveTeam();
|
||||||
|
|
||||||
|
// Remove duplicate avatars.
|
||||||
|
var avatars = this.getActiveTeam();
|
||||||
|
var avatarIds = new HashSet<Long>();
|
||||||
|
for (var entityAvatar : new ArrayList<>(avatars)) {
|
||||||
|
if (avatarIds.contains(entityAvatar.getAvatar().getGuid())) {
|
||||||
|
avatars.remove(entityAvatar);
|
||||||
|
} else {
|
||||||
|
avatarIds.add(entityAvatar.getAvatar().getGuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return avatars; // Return the fixed team.
|
||||||
|
}
|
||||||
|
|
||||||
public EntityAvatar getCurrentAvatarEntity() {
|
public EntityAvatar getCurrentAvatarEntity() {
|
||||||
if (this.currentCharacterIndex >= this.getActiveTeam().size()) {
|
if (this.currentCharacterIndex >= this.getActiveTeam().size()) {
|
||||||
this.currentCharacterIndex = 0; // Reset to the first character.
|
this.currentCharacterIndex = 0; // Reset to the first character.
|
||||||
@@ -557,8 +581,6 @@ public final class TeamManager extends BasePlayerDataManager {
|
|||||||
} else {
|
} else {
|
||||||
// Restores all avatars from the player's avatar storage.
|
// Restores all avatars from the player's avatar storage.
|
||||||
// If the avatar is already in the team, it will not be added.
|
// If the avatar is already in the team, it will not be added.
|
||||||
// TODO: Fix order in which avatars are added.
|
|
||||||
// Currently, they are added from last to first.
|
|
||||||
var avatars = this.getCurrentTeamInfo().getAvatars();
|
var avatars = this.getCurrentTeamInfo().getAvatars();
|
||||||
for (var index = 0; index < avatars.size(); index++) {
|
for (var index = 0; index < avatars.size(); index++) {
|
||||||
var avatar = avatars.get(index);
|
var avatar = avatars.get(index);
|
||||||
@@ -804,7 +826,7 @@ public final class TeamManager extends BasePlayerDataManager {
|
|||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
player
|
this.getPlayer()
|
||||||
.getStaminaManager()
|
.getStaminaManager()
|
||||||
.stopSustainedStaminaHandler(); // prevent drowning immediately after respawn
|
.stopSustainedStaminaHandler(); // prevent drowning immediately after respawn
|
||||||
|
|
||||||
@@ -813,7 +835,7 @@ public final class TeamManager extends BasePlayerDataManager {
|
|||||||
entity.setFightProperty(
|
entity.setFightProperty(
|
||||||
FightProperty.FIGHT_PROP_CUR_HP,
|
FightProperty.FIGHT_PROP_CUR_HP,
|
||||||
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * .4f);
|
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * .4f);
|
||||||
player.getSatiationManager().removeSatiationDirectly(entity.getAvatar(), 15000);
|
this.getPlayer().getSatiationManager().removeSatiationDirectly(entity.getAvatar(), 15000);
|
||||||
this.getPlayer()
|
this.getPlayer()
|
||||||
.sendPacket(
|
.sendPacket(
|
||||||
new PacketAvatarFightPropUpdateNotify(
|
new PacketAvatarFightPropUpdateNotify(
|
||||||
@@ -829,10 +851,10 @@ public final class TeamManager extends BasePlayerDataManager {
|
|||||||
this.getPlayer(),
|
this.getPlayer(),
|
||||||
EnterType.ENTER_TYPE_SELF,
|
EnterType.ENTER_TYPE_SELF,
|
||||||
EnterReason.Revival,
|
EnterReason.Revival,
|
||||||
player.getSceneId(),
|
this.getPlayer().getSceneId(),
|
||||||
getRespawnPosition()));
|
this.getRespawnPosition()));
|
||||||
player.getPosition().set(getRespawnPosition());
|
this.getPlayer().getPosition().set(this.getRespawnPosition());
|
||||||
} catch (Exception e) {
|
} catch (Exception ignored) {
|
||||||
this.getPlayer()
|
this.getPlayer()
|
||||||
.sendPacket(
|
.sendPacket(
|
||||||
new PacketPlayerEnterSceneNotify(
|
new PacketPlayerEnterSceneNotify(
|
||||||
@@ -841,7 +863,7 @@ public final class TeamManager extends BasePlayerDataManager {
|
|||||||
EnterReason.Revival,
|
EnterReason.Revival,
|
||||||
3,
|
3,
|
||||||
GameConstants.START_POSITION));
|
GameConstants.START_POSITION));
|
||||||
player
|
this.getPlayer()
|
||||||
.getPosition()
|
.getPosition()
|
||||||
.set(GameConstants.START_POSITION); // If something goes wrong, the resurrection is here
|
.set(GameConstants.START_POSITION); // If something goes wrong, the resurrection is here
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import emu.grasscutter.net.proto.SceneTeamAvatarOuterClass.SceneTeamAvatar;
|
|||||||
import emu.grasscutter.net.proto.SceneTeamUpdateNotifyOuterClass.SceneTeamUpdateNotify;
|
import emu.grasscutter.net.proto.SceneTeamUpdateNotifyOuterClass.SceneTeamUpdateNotify;
|
||||||
|
|
||||||
public class PacketSceneTeamUpdateNotify extends BasePacket {
|
public class PacketSceneTeamUpdateNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketSceneTeamUpdateNotify(Player player) {
|
public PacketSceneTeamUpdateNotify(Player player) {
|
||||||
super(PacketOpcodes.SceneTeamUpdateNotify);
|
super(PacketOpcodes.SceneTeamUpdateNotify);
|
||||||
|
|
||||||
@@ -16,7 +15,7 @@ public class PacketSceneTeamUpdateNotify extends BasePacket {
|
|||||||
.setIsInMp(player.getWorld().isMultiplayer());
|
.setIsInMp(player.getWorld().isMultiplayer());
|
||||||
|
|
||||||
for (var p : player.getWorld().getPlayers()) {
|
for (var p : player.getWorld().getPlayers()) {
|
||||||
for (var entityAvatar : p.getTeamManager().getActiveTeam()) {
|
for (var entityAvatar : p.getTeamManager().getActiveTeam(true)) {
|
||||||
var avatarProto =
|
var avatarProto =
|
||||||
SceneTeamAvatar.newBuilder()
|
SceneTeamAvatar.newBuilder()
|
||||||
.setPlayerUid(p.getUid())
|
.setPlayerUid(p.getUid())
|
||||||
|
|||||||
Reference in New Issue
Block a user