Fix default Traveler

This commit is contained in:
KingRainbow44 2023-04-14 00:31:46 -04:00
parent af01282594
commit 6c1cff38b4
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
2 changed files with 85 additions and 124 deletions

View File

@ -44,6 +44,8 @@ import it.unimi.dsi.fastutil.ints.*;
import java.util.*;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@ -59,7 +61,7 @@ public class Avatar {
@Indexed @Getter private int ownerId; // Id of player that this avatar belongs to
@Transient private Player owner;
@Transient @Getter private AvatarData avatarData;
@Transient @Getter private AvatarSkillDepotData skillDepot;
@Nullable @Transient @Getter private AvatarSkillDepotData skillDepot;
@Transient @Getter private long guid; // Player unique id
@Getter private int avatarId; // Id of avatar
@Getter @Setter private int level = 1;
@ -123,6 +125,7 @@ public class Avatar {
public Avatar(AvatarData data) {
this();
this.avatarId = data.getId();
this.nameCardRewardId = data.getNameCardRewardId();
this.nameCardId = data.getNameCardId();
@ -135,19 +138,17 @@ public class Avatar {
// Combat properties
Stream.of(FightProperty.values())
.map(FightProperty::getId)
.filter(id -> (id > 0) && (id < 3000))
.forEach(id -> this.setFightProperty(id, 0f));
.map(FightProperty::getId)
.filter(id -> (id > 0) && (id < 3000))
.forEach(id -> this.setFightProperty(id, 0f));
// Skill depot
this.setSkillDepotData(
switch (this.avatarId) {
case GameConstants.MAIN_CHARACTER_MALE -> GameData.getAvatarSkillDepotDataMap()
.get(504); // Hack to start with anemo skills
case GameConstants.MAIN_CHARACTER_FEMALE -> GameData.getAvatarSkillDepotDataMap()
.get(704);
default -> data.getSkillDepot();
});
this.setSkillDepotData(switch (this.getAvatarId()) {
case GameConstants.MAIN_CHARACTER_MALE ->
GameData.getAvatarSkillDepotDataMap().get(501);
case GameConstants.MAIN_CHARACTER_FEMALE ->
GameData.getAvatarSkillDepotDataMap().get(701);
default -> data.getSkillDepot();
});
// Set stats
this.recalcStats();
@ -175,6 +176,16 @@ public class Avatar {
return 0;
}
/**
* @return True if the avatar is a main character.
*/
public boolean isMainCharacter() {
return List.of(
GameConstants.MAIN_CHARACTER_MALE,
GameConstants.MAIN_CHARACTER_FEMALE
).contains(this.getAvatarId());
}
public Player getPlayer() {
return this.owner;
}
@ -192,6 +203,11 @@ public class Avatar {
this.owner = player;
this.ownerId = player.getUid();
this.guid = player.getNextGameGuid();
if (this.isMainCharacter()) {
// Apply skill depot based on player resonance.
this.changeElement(player.getMainCharacterElement(), false);
}
}
public boolean addSatiation(int value) {
@ -273,14 +289,28 @@ public class Avatar {
}
/**
* Changes the avatar's element to the target element, if the character has values for it set in
* the candSkillDepot
* Changes the avatar's element to the target element.
* Only applies if the avatar has the element in its 'candSkillDepot's.
*
* @param elementTypeToChange element to change to
* @return false if failed or already using that element, true if it actually changed
* @param newElement The new element to change to.
* @return True if the element was changed, false otherwise.
*/
public boolean changeElement(@Nonnull ElementType elementTypeToChange) {
var candSkillDepotIdsList = this.avatarData.getCandSkillDepotIds();
public boolean changeElement(@Nonnull ElementType newElement) {
return this.changeElement(newElement, true);
}
/**
* Changes the avatar's element to the target element.
* Only applies if the avatar has the element in its 'candSkillDepot's.
*
* @param elementTypeToChange The new element to change to.
* @param notify Whether to notify the player of the change.
* @return True if the element was changed, false otherwise.
*/
public boolean changeElement(@Nonnull ElementType elementTypeToChange, boolean notify) {
if (elementTypeToChange == ElementType.None) return true;
var candSkillDepotIdsList = this.getAvatarData().getCandSkillDepotIds();
var candSkillDepotIndex = elementTypeToChange.getDepotIndex();
// if no candidate skill to change or index out of bound
@ -297,7 +327,9 @@ public class Avatar {
}
// Set skill depot
setSkillDepotData(skillDepot, true);
this.setSkillDepotData(skillDepot, notify);
// Set element.
this.getPlayer().setMainCharacterElement(elementTypeToChange);
return true;
}
@ -383,17 +415,21 @@ public class Avatar {
}
public IntSet getTalentIdList() { // Returns a copy of the unlocked constellations for the current
// skillDepot.
var talents = new IntOpenHashSet(this.getSkillDepot().getTalents());
talents.removeIf(id -> !this.talentIdList.contains(id));
return talents;
if (this.getSkillDepot() != null) {
// skillDepot.
var talents = new IntOpenHashSet(this.getSkillDepot().getTalents());
talents.removeIf(id -> !this.talentIdList.contains(id));
return talents;
} else return new IntOpenHashSet();
}
public int getCoreProudSkillLevel() {
var lockedTalents = new IntOpenHashSet(this.getSkillDepot().getTalents());
lockedTalents.removeAll(this.getTalentIdList());
// One below the lowest locked talent, or 6 if there are no locked talents.
return lockedTalents.intStream().map(i -> i % 10).min().orElse(7) - 1;
if (this.getSkillDepot() != null) {
var lockedTalents = new IntOpenHashSet(this.getSkillDepot().getTalents());
lockedTalents.removeAll(this.getTalentIdList());
// One below the lowest locked talent, or 6 if there are no locked talents.
return lockedTalents.intStream().map(i -> i % 10).min().orElse(7) - 1;
} else return 0;
}
public boolean equipItem(GameItem item, boolean shouldRecalc) {
@ -624,14 +660,16 @@ public class Avatar {
AvatarSkillDepotData skillDepot =
GameData.getAvatarSkillDepotDataMap().get(this.getSkillDepotId());
this.getProudSkillList().clear();
for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) {
if (openData.getProudSkillGroupId() == 0) {
continue;
}
if (openData.getNeedAvatarPromoteLevel() <= this.getPromoteLevel()) {
int proudSkillId = (openData.getProudSkillGroupId() * 100) + 1;
if (GameData.getProudSkillDataMap().containsKey(proudSkillId)) {
this.getProudSkillList().add(proudSkillId);
if (skillDepot != null) {
for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) {
if (openData.getProudSkillGroupId() == 0) {
continue;
}
if (openData.getNeedAvatarPromoteLevel() <= this.getPromoteLevel()) {
int proudSkillId = (openData.getProudSkillGroupId() * 100) + 1;
if (GameData.getProudSkillDataMap().containsKey(proudSkillId)) {
this.getProudSkillList().add(proudSkillId);
}
}
}
}

View File

@ -40,10 +40,7 @@ import emu.grasscutter.game.managers.forging.ForgingManager;
import emu.grasscutter.game.managers.mapmark.MapMark;
import emu.grasscutter.game.managers.mapmark.MapMarksManager;
import emu.grasscutter.game.managers.stamina.StaminaManager;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.ClimateType;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.props.WatcherTriggerType;
import emu.grasscutter.game.props.*;
import emu.grasscutter.game.quest.QuestManager;
import emu.grasscutter.game.quest.enums.QuestCond;
import emu.grasscutter.game.quest.enums.QuestContent;
@ -64,7 +61,6 @@ import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord.GrantReason;
import emu.grasscutter.scripts.data.SceneRegion;
import emu.grasscutter.server.event.player.PlayerJoinEvent;
import emu.grasscutter.server.event.player.PlayerQuitEvent;
@ -88,7 +84,6 @@ import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.Stream;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
@ -213,6 +208,8 @@ public class Player {
@Getter private PlayerProgress playerProgress;
@Getter private Set<Integer> activeQuestTimers;
@Getter @Setter private ElementType mainCharacterElement = ElementType.None;
@Deprecated
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
public Player() {
@ -291,6 +288,7 @@ public class Player {
// On player creation
public Player(GameSession session) {
this();
this.account = session.getAccount();
this.accountId = this.getAccount().getId();
this.session = session;
@ -300,6 +298,10 @@ public class Player {
this.birthday = new PlayerBirthday();
this.codex = new PlayerCodex(this);
this.applyProperties();
this.getFlyCloakList().add(140001);
this.getNameCardList().add(210001);
this.messageHandler = null;
this.mapMarksManager = new MapMarksManager(this);
this.staminaManager = new StaminaManager(this);
@ -313,10 +315,6 @@ public class Player {
this.cookingManager = new CookingManager(this);
this.cookingCompoundManager = new CookingCompoundManager(this);
this.satiationManager = new SatiationManager(this);
this.applyProperties();
this.getFlyCloakList().add(140001);
this.getNameCardList().add(210001);
}
/**
@ -537,10 +535,9 @@ public class Player {
* @param defaultValue The value to apply if the property doesn't exist.
*/
private void setOrFetch(PlayerProperty property, int defaultValue) {
if (!this.properties.containsKey(property.getId())) {
this.setProperty(property, defaultValue, false);
this.save();
}
this.setProperty(property,
this.properties.containsKey(property.getId()) ?
this.getProperty(property) : defaultValue, false);
}
public int getPrimogems() {
@ -864,80 +861,6 @@ public class Player {
addAvatar(new Avatar(avatarId), true);
}
public List<Integer> getTrialAvatarParam (int trialAvatarId) {
if (GameData.getTrialAvatarCustomData().isEmpty()) { // use default data if custom data not available
if (GameData.getTrialAvatarDataMap().get(trialAvatarId) == null) return List.of();
return GameData.getTrialAvatarDataMap().get(trialAvatarId)
.getTrialAvatarParamList();
}
// use custom data
if (GameData.getTrialAvatarCustomData().get(trialAvatarId) == null) return List.of();
var trialCustomParams = GameData.getTrialAvatarCustomData().get(trialAvatarId).getTrialAvatarParamList();
return trialCustomParams.isEmpty() ? List.of() : Stream.of(trialCustomParams.get(0).split(";")).map(Integer::parseInt).toList();
}
public boolean addTrialAvatar(int trialAvatarId, GrantReason reason, int questMainId){
List<Integer> trialAvatarBasicParam = getTrialAvatarParam(trialAvatarId);
if (trialAvatarBasicParam.isEmpty()) return false;
Avatar avatar = new Avatar(trialAvatarBasicParam.get(0));
if (avatar.getAvatarData() == null || !hasSentLoginPackets()) return false;
avatar.setOwner(this);
// Add trial weapons and relics
avatar.setTrialAvatarInfo(trialAvatarBasicParam.get(1), trialAvatarId, reason, questMainId);
avatar.equipTrialItems();
// Recalc stats
avatar.recalcStats();
// Packet, mimic official server behaviour, add to player's bag but not saving to db
sendPacket(new PacketAvatarAddNotify(avatar, false));
// add to avatar to temporary trial team
getTeamManager().addAvatarToTrialTeam(avatar);
return true;
}
public boolean addTrialAvatarForQuest(int trialAvatarId, int questMainId) {
// TODO: Find method for 'setupTrialAvatarTeamForQuest'.
getTeamManager().setupTrialAvatars(true);
if (!addTrialAvatar(
trialAvatarId,
GrantReason.GRANT_REASON_BY_QUEST,
questMainId)) return false;
getTeamManager().trialAvatarTeamPostUpdate();
// Packet, mimic official server behaviour, neccessary to stop player from modifying team
sendPacket(new PacketAvatarTeamUpdateNotify(this));
return true;
}
public void addTrialAvatarsForActivity(List<Integer> trialAvatarIds) {
getTeamManager().setupTrialAvatars(false);
trialAvatarIds.forEach(trialAvatarId -> addTrialAvatar(
trialAvatarId,
GrantReason.GRANT_REASON_BY_TRIAL_AVATAR_ACTIVITY,
0));
getTeamManager().trialAvatarTeamPostUpdate(0);
}
public boolean removeTrialAvatarForQuest(int trialAvatarId) {
if (!getTeamManager().isUsingTrialTeam()) return false;
sendPacket(new PacketAvatarDelNotify(List.of(getTeamManager().getTrialAvatarGuid(trialAvatarId))));
getTeamManager().removeTrialAvatarTeam(trialAvatarId);
sendPacket(new PacketAvatarTeamUpdateNotify());
return true;
}
public void removeTrialAvatarForActivity() {
if (!getTeamManager().isUsingTrialTeam()) return;
sendPacket(new PacketAvatarDelNotify(getTeamManager().getActiveTeam().stream()
.map(x -> x.getAvatar().getGuid()).toList()));
getTeamManager().removeTrialAvatarTeam();
}
public void addFlycloak(int flycloakId) {
this.getFlyCloakList().add(flycloakId);
this.sendPacket(new PacketAvatarGainFlycloakNotify(flycloakId));