Commit 92aeb79a authored by akatatsu27's avatar akatatsu27 Committed by GitHub
Browse files

Merge branch 'development' into questing

parents 44d8a648 1c5c3633
...@@ -240,7 +240,7 @@ public final class GiveCommand implements CommandHandler { ...@@ -240,7 +240,7 @@ public final class GiveCommand implements CommandHandler {
} }
private static Avatar makeAvatar(GiveItemParameters param) { private static Avatar makeAvatar(GiveItemParameters param) {
return makeAvatar(param.avatarData, param.lvl, Avatar.getMinPromoteLevel(param.lvl), 0); return makeAvatar(param.avatarData, param.lvl, Avatar.getMinPromoteLevel(param.lvl), param.constellation);
} }
private static Avatar makeAvatar(AvatarData avatarData, int level, int promoteLevel, int constellation) { private static Avatar makeAvatar(AvatarData avatarData, int level, int promoteLevel, int constellation) {
......
package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.AvatarTalentData;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.game.world.World;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import java.util.List;
import java.util.Set;
@Command(
label = "setConst",
aliases = {"setconstellation"},
usage = {"<constellation level>"},
permission = "player.setconstellation",
permissionTargeted = "player.setconstellation.others")
public final class SetConstCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) {
sendUsageMessage(sender);
return;
}
try {
int constLevel = Integer.parseInt(args.get(0));
if (constLevel < 0 || constLevel > 6) {
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.range_error");
return;
}
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
if (entity == null) return;
Avatar avatar = entity.getAvatar();
this.setConstellation(targetPlayer, avatar, constLevel);
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.success", avatar.getAvatarData().getName(), constLevel);
} catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.level_error");
}
}
private void setConstellation(Player player, Avatar avatar, int constLevel) {
int currentConstLevel = avatar.getCoreProudSkillLevel();
IntArrayList talentIds = new IntArrayList(avatar.getSkillDepot().getTalents());
Set<Integer> talentIdList = avatar.getTalentIdList();
talentIdList.clear();
avatar.setCoreProudSkillLevel(0);
for(int talent = 0; talent < constLevel; talent++) {
AvatarTalentData talentData = GameData.getAvatarTalentDataMap().get(talentIds.getInt(talent));
int mainCostItemId = talentData.getMainCostItemId();
player.getInventory().addItem(mainCostItemId);
Grasscutter.getGameServer().getInventorySystem().unlockAvatarConstellation(player, avatar.getGuid());
}
// force player to reload scene when necessary
if (constLevel < currentConstLevel) {
World world = player.getWorld();
Scene scene = player.getScene();
Position pos = player.getPosition();
world.transferPlayerToScene(player, 1, pos);
world.transferPlayerToScene(player, scene.getId(), pos);
scene.broadcastPacket(new PacketSceneEntityAppearNotify(player));
}
// ensure that all changes are visible to the player
avatar.recalcConstellations();
avatar.recalcStats(true);
avatar.save();
}
}
...@@ -8,6 +8,7 @@ import java.util.Map; ...@@ -8,6 +8,7 @@ import java.util.Map;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.*; import emu.grasscutter.data.binout.*;
import emu.grasscutter.game.quest.QuestEncryptionKey;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import emu.grasscutter.data.excels.*; import emu.grasscutter.data.excels.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
...@@ -25,6 +26,7 @@ public class GameData { ...@@ -25,6 +26,7 @@ public class GameData {
private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>(); private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>(); private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<QuestEncryptionKey> questsKeys = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<HomeworldDefaultSaveData> homeworldDefaultSaveData = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<HomeworldDefaultSaveData> homeworldDefaultSaveData = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>();
...@@ -169,6 +171,10 @@ public class GameData { ...@@ -169,6 +171,10 @@ public class GameData {
return mainQuestData; return mainQuestData;
} }
public static Int2ObjectMap<QuestEncryptionKey> getMainQuestEncryptionMap() {
return questsKeys;
}
public static Int2ObjectMap<HomeworldDefaultSaveData> getHomeworldDefaultSaveData() { public static Int2ObjectMap<HomeworldDefaultSaveData> getHomeworldDefaultSaveData() {
return homeworldDefaultSaveData; return homeworldDefaultSaveData;
} }
......
package emu.grasscutter.data; package emu.grasscutter.data;
import java.io.*;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import emu.grasscutter.data.binout.*;
import emu.grasscutter.game.world.SpawnDataEntry;
import emu.grasscutter.scripts.SceneIndexManager;
import emu.grasscutter.utils.Utils;
import lombok.SneakyThrows;
import org.reflections.Reflections;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.*;
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData; import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction; import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType; import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
import emu.grasscutter.data.common.PointData; import emu.grasscutter.data.common.PointData;
import emu.grasscutter.data.common.ScenePointConfig; import emu.grasscutter.data.common.ScenePointConfig;
import emu.grasscutter.game.world.SpawnDataEntry.*; import emu.grasscutter.game.quest.QuestEncryptionKey;
import emu.grasscutter.game.world.SpawnDataEntry;
import emu.grasscutter.game.world.SpawnDataEntry.GridBlockId;
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
import emu.grasscutter.scripts.SceneIndexManager;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import lombok.SneakyThrows;
import org.reflections.Reflections;
import java.io.*;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static emu.grasscutter.config.Configuration.*; import static emu.grasscutter.config.Configuration.RESOURCE;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
public class ResourceLoader { public class ResourceLoader {
...@@ -418,6 +418,18 @@ public class ResourceLoader { ...@@ -418,6 +418,18 @@ public class ResourceLoader {
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest); GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
} }
try (Reader reader = DataLoader.loadReader("QuestEncryptionKeys.json")) {
List<QuestEncryptionKey> keys = Grasscutter.getGsonFactory().fromJson(
reader,
TypeToken.getParameterized(List.class, QuestEncryptionKey.class).getType());
Int2ObjectMap<QuestEncryptionKey> questEncryptionMap = GameData.getMainQuestEncryptionMap();
keys.forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
Grasscutter.getLogger().info("loaded {} quest keys.", questEncryptionMap.size());
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load quest keys.", e);
}
Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas."); Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
} }
......
...@@ -219,6 +219,7 @@ public class EntityGadget extends EntityBaseGadget { ...@@ -219,6 +219,7 @@ public class EntityGadget extends EntityBaseGadget {
.setConfigId(this.getConfigId()) .setConfigId(this.getConfigId())
.setGadgetState(this.getState()) .setGadgetState(this.getState())
.setIsEnableInteract(true) .setIsEnableInteract(true)
.setDraftId(this.metaGadget.draft_id)
.setAuthorityPeerId(this.getScene().getWorld().getHostPeerId()); .setAuthorityPeerId(this.getScene().getWorld().getHostPeerId());
if (this.getContent() != null) { if (this.getContent() != null) {
......
...@@ -342,13 +342,10 @@ public class GameMainQuest { ...@@ -342,13 +342,10 @@ public class GameMainQuest {
ParentQuest.Builder proto = ParentQuest.newBuilder() ParentQuest.Builder proto = ParentQuest.newBuilder()
.setParentQuestId(getParentQuestId()) .setParentQuestId(getParentQuestId())
.setIsFinished(isFinished()); .setIsFinished(isFinished());
/**
if ParentQuestState is NONE, official server does not send ParentQuestState nor childQuestList!!!
might need more sniffing...
sending childQuestList without ParentQuestState set causes the game to hang on login
*/
if (getState() != ParentQuestState.PARENT_QUEST_STATE_NONE) {
proto.setParentQuestState(getState().getValue()); proto.setParentQuestState(getState().getValue());
.setCutsceneEncryptionKey(QuestManager.getQuestKey(parentQuestId));
for (GameQuest quest : this.getChildQuests().values()) { for (GameQuest quest : this.getChildQuests().values()) {
if (quest.getState() != QuestState.QUEST_STATE_UNSTARTED) { if (quest.getState() != QuestState.QUEST_STATE_UNSTARTED) {
ChildQuest childQuest = ChildQuest.newBuilder() ChildQuest childQuest = ChildQuest.newBuilder()
...@@ -359,11 +356,12 @@ public class GameMainQuest { ...@@ -359,11 +356,12 @@ public class GameMainQuest {
proto.addChildQuestList(childQuest); proto.addChildQuestList(childQuest);
} }
} }
}
for (int i : getQuestVars()) { for (int i : getQuestVars()) {
proto.addQuestVar(i); proto.addQuestVar(i);
} }
return proto.build(); return proto.build();
} }
......
package emu.grasscutter.game.quest;
import lombok.AccessLevel;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class QuestEncryptionKey {
int mainQuestId;
long encryptionKey;
}
...@@ -3,8 +3,6 @@ package emu.grasscutter.game.quest; ...@@ -3,8 +3,6 @@ package emu.grasscutter.game.quest;
import java.beans.Transient; import java.beans.Transient;
import java.util.*; import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.MainQuestData; import emu.grasscutter.data.binout.MainQuestData;
...@@ -25,6 +23,7 @@ import jdk.jshell.spi.ExecutionControl; ...@@ -25,6 +23,7 @@ import jdk.jshell.spi.ExecutionControl;
import lombok.Getter; import lombok.Getter;
public class QuestManager extends BasePlayerManager { public class QuestManager extends BasePlayerManager {
@Getter private final Player player; @Getter private final Player player;
@Getter private Map<Integer,Integer> questGlobalVariables; @Getter private Map<Integer,Integer> questGlobalVariables;
...@@ -64,7 +63,13 @@ public class QuestManager extends BasePlayerManager { ...@@ -64,7 +63,13 @@ public class QuestManager extends BasePlayerManager {
); );
*/ */
public static long getQuestKey(int mainQuestId){
QuestEncryptionKey questEncryptionKey = GameData.getMainQuestEncryptionMap().get(mainQuestId);
return questEncryptionKey != null ? questEncryptionKey.getEncryptionKey() : 0L;
}
public QuestManager(Player player) { public QuestManager(Player player) {
super(player); super(player);
this.player = player; this.player = player;
this.questGlobalVariables = player.getQuestGlobalVariables(); this.questGlobalVariables = player.getQuestGlobalVariables();
......
...@@ -12,6 +12,7 @@ public class SceneGadget extends SceneObject{ ...@@ -12,6 +12,7 @@ public class SceneGadget extends SceneObject{
public SceneBossChest boss_chest; public SceneBossChest boss_chest;
public int interact_id; public int interact_id;
public boolean isOneoff; public boolean isOneoff;
public int draft_id;
public void setIsOneoff(boolean isOneoff){ public void setIsOneoff(boolean isOneoff){
this.isOneoff = isOneoff; this.isOneoff = isOneoff;
......
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "Message sent.", "success": "Message sent.",
"description": "Sends a message to a player as the server. If used with no target, sends to all players on the server." "description": "Sends a message to a player as the server. If used with no target, sends to all players on the server."
}, },
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "Fetter level must be between 0 and 10.", "range_error": "Fetter level must be between 0 and 10.",
"success": "Fetter level set to %s.", "success": "Fetter level set to %s.",
......
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "Mensaje enviado.", "success": "Mensaje enviado.",
"description": "Envía un mensaje a un jugador como servidor. Si se usa sin un objetivo fijado, lo envía a todos los jugadores del servidor." "description": "Envía un mensaje a un jugador como servidor. Si se usa sin un objetivo fijado, lo envía a todos los jugadores del servidor."
}, },
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "El nivel de amistad debe estar entre 0 y 10.", "range_error": "El nivel de amistad debe estar entre 0 y 10.",
"success": "Nivel de amistad establecido a %s.", "success": "Nivel de amistad establecido a %s.",
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
"login_token_attempt": "[Dispatch] Le client %s essaye de se connecter via un jeton.", "login_token_attempt": "[Dispatch] Le client %s essaye de se connecter via un jeton.",
"login_token_error": "[Dispatch] Le client %s n'a pas réussi à se connecter via un jeton.", "login_token_error": "[Dispatch] Le client %s n'a pas réussi à se connecter via un jeton.",
"login_token_success": "[Dispatch] Le client %s est connecté via un jeton en tant que %s.", "login_token_success": "[Dispatch] Le client %s est connecté via un jeton en tant que %s.",
"login_password_error": "🇺🇸[Dispatch] Client %s failed to log in via password.", "login_password_error": "[Dispatch] Le client %s n'a pas réussi a se connecter avec un mot de passe",
"login_password_storage_error": "🇺🇸[Dispatch] Client %s failed to log in via password because there is no password in the database.", "login_password_storage_error": "[Dispatch] Le client %s n'a pas réussi a se conencter avec un mot de passe car il n'y a pass de mot de passe dans la base de données",
"combo_token_success": "[Dispatch] Le client %s a réussi à échanger le jeton combiné.", "combo_token_success": "[Dispatch] Le client %s a réussi à échanger le jeton combiné.",
"combo_token_error": "[Dispatch] Le client %s n'a pas réussi à échanger le jeton combiné.", "combo_token_error": "[Dispatch] Le client %s n'a pas réussi à échanger le jeton combiné.",
"account_login_create_success": "[Dispatch] Le client %s n'a pas réussi à se connecter : Le compte %s a été créé.", "account_login_create_success": "[Dispatch] Le client %s n'a pas réussi à se connecter : Le compte %s a été créé.",
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
"session_key_error": "Mauvaise clé de session.", "session_key_error": "Mauvaise clé de session.",
"username_error": "Nom d'utilisateur introuvable.", "username_error": "Nom d'utilisateur introuvable.",
"username_create_error": "Nom d'utilisateur introuvable, création échouée.", "username_create_error": "Nom d'utilisateur introuvable, création échouée.",
"password_error": "🇺🇸Invalid Password", "password_error": "Mot de passe invalide",
"password_length_error": "🇺🇸Password length must be greater then or equal to 8", "password_length_error": "La longueur du mot de passe doit être supérieure a 8",
"password_storage_error": "🇺🇸You don't have a password for your account. Please contact an administrator.", "password_storage_error": "Vous n'avez pas de mot de passe pour votre compte. Veuillez contacter un administrateur.",
"server_max_player_limit": "Le nombre de joueurs maximum est atteint." "server_max_player_limit": "Le nombre de joueurs maximum est atteint."
}, },
"router_error": "[Dispatch] Impossible d'attacher le routeur." "router_error": "[Dispatch] Impossible d'attacher le routeur."
...@@ -60,8 +60,8 @@ ...@@ -60,8 +60,8 @@
"version": "Version de Grasscutter: %s-%s", "version": "Version de Grasscutter: %s-%s",
"game_version": "Version du jeu: %s", "game_version": "Version du jeu: %s",
"resources": { "resources": {
"loading": "🇺🇸Loading resources...", "loading": "Chargement des ressources...",
"finish": "🇺🇸Finished loading resources." "finish": "Chargement des ressources terminé."
} }
} }
}, },
...@@ -87,14 +87,14 @@ ...@@ -87,14 +87,14 @@
"itemLevel": "Niveau de l'objet invalide.", "itemLevel": "Niveau de l'objet invalide.",
"itemRefinement": "Raffinement de l'objet invalide.", "itemRefinement": "Raffinement de l'objet invalide.",
"statValue": "Valeur de <stat> invalide.", "statValue": "Valeur de <stat> invalide.",
"value_between": "🇺🇸Invalid value: %s must be between %s and %s.", "value_between": "Valeur invalide: %s doit être compris entre %s et %s.",
"playerId": "ID du joueur invalide.", "playerId": "ID du joueur invalide.",
"uid": "UID invalide.", "uid": "UID invalide.",
"id": "ID invalide." "id": "ID invalide."
} }
}, },
"execution": { "execution": {
"usage_prefix": "🇺🇸Usage: ", "usage_prefix": "Utilisation: ",
"player_exist_error": "Joueur introuvable.", "player_exist_error": "Joueur introuvable.",
"player_offline_error": "Le joueur n'est pas connecté.", "player_offline_error": "Le joueur n'est pas connecté.",
"item_player_exist_error": "UID ou objet invalide.", "item_player_exist_error": "UID ou objet invalide.",
...@@ -123,11 +123,11 @@ ...@@ -123,11 +123,11 @@
"description": "Modifie les comptes utilisateurs" "description": "Modifie les comptes utilisateurs"
}, },
"announce": { "announce": {
"send_success": "🇺🇸Send an announcement successfully, you can revoke it by /a revoke %s.", "send_success": "L'annonce à bien été envoyée, vous pouvez la révoquer en utilisant /a revoke %s.",
"refresh_success": "🇺🇸Refresh announcement config file successfully. [Total %s]", "refresh_success": "Le fichier de configuration des annonces à bien été actualisée. [Total : %s]",
"revoke_done": "🇺🇸Try to revoke announcement %s.", "revoke_done": "Tentative de révoquation de l'annonce %s.",
"not_found": "🇺🇸Could not found announcement %s.", "not_found": "Impossible de trouver l'annonce %s.",
"description": "🇺🇸Send announcement to all online players, or manage server's announcement" "description": "Envoie une annonce à tous les joueurs en ligne, ou configure les annonces du serveur"
}, },
"clear": { "clear": {
"weapons": "Les armes de %s ont été supprimés.", "weapons": "Les armes de %s ont été supprimés.",
...@@ -150,13 +150,13 @@ ...@@ -150,13 +150,13 @@
"description": "Entrer dans un donjon" "description": "Entrer dans un donjon"
}, },
"give": { "give": {
"usage_relic": "🇺🇸Usage: give <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<level 0-20>]", "usage_relic": "Utilisation: give <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<level 0-20>]",
"illegal_relic": "🇺🇸This artifactID belongs to a blacklisted range, it may not be the one you wanted.", "illegal_relic": "L'ID de cet artéfact appartient a une liste blacklistée, ce n'est peut-être pas celui que vous désirez.",
"given": "🇺🇸Given %s of %s to %s.", "given": "L'objet %s à été donné %s fois à %s",
"given_with_level_and_refinement": "%s avec le niveau %s, raffinement %s %s fois à %s.", "given_with_level_and_refinement": "%s avec le niveau %s, raffinement %s %s fois à %s.",
"given_level": "%s avec le niveau %s %s fois à %s.", "given_level": "%s avec le niveau %s %s fois à %s.",
"given_avatar": "%s avec le niveau %s a été donné à %s.", "given_avatar": "%s avec le niveau %s a été donné à %s.",
"giveall_success": "🇺🇸Successfully gave all items.", "giveall_success": "Tous les objet ont été donnés avec succès.",
"description": "Donne un objet au joueur spécifié" "description": "Donne un objet au joueur spécifié"
}, },
"heal": { "heal": {
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
"help": { "help": {
"aliases": "Alias: ", "aliases": "Alias: ",
"available_commands": "Commandes disponibles: ", "available_commands": "Commandes disponibles: ",
"tip_need_permission": "🇺🇸Permission: ", "tip_need_permission": "Permissions requises: ",
"tip_need_no_permission": " Aucune", "tip_need_no_permission": " Aucune",
"tip_permission_targeted": " (La permission %s est également requise pour utiliser sur d'autres joueurs)", "tip_permission_targeted": " (La permission %s est également requise pour utiliser sur d'autres joueurs)",
"warn_player_has_no_permission": "Information: Vous n'avez pas la permission d'utiliser cette commande.", "warn_player_has_no_permission": "Information: Vous n'avez pas la permission d'utiliser cette commande.",
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
"send": "%s %s (niveau %s) ont été ajouté au message.\nContinuez d'ajouter plus d'objets ou utilisez '/sendmail finish' pour envoyer le message.", "send": "%s %s (niveau %s) ont été ajouté au message.\nContinuez d'ajouter plus d'objets ou utilisez '/sendmail finish' pour envoyer le message.",
"invalid_arguments_please_use": "Arguments invalides.\n Veuillez utiliser '/sendmail %s'", "invalid_arguments_please_use": "Arguments invalides.\n Veuillez utiliser '/sendmail %s'",
"title": "<titre>", "title": "<titre>",
"message": "🇺🇸<message>", "message": "<message>",
"sender": "<expéditeur>", "sender": "<expéditeur>",
"arguments": "<itemID|itemName|finish> [quantité] [niveau]", "arguments": "<itemID|itemName|finish> [quantité] [niveau]",
"error": "ERREUR: Stade de construction invalide : %s. Vérifiez la console pour la pile d'appels.", "error": "ERREUR: Stade de construction invalide : %s. Vérifiez la console pour la pile d'appels.",
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "Message envoyé.", "success": "Message envoyé.",
"description": "Envoie un message au joueur spécifié en tant que Serveur" "description": "Envoie un message au joueur spécifié en tant que Serveur"
}, },
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "Le niveau d'affinité doit être compris entre 0 et 10.", "range_error": "Le niveau d'affinité doit être compris entre 0 et 10.",
"success": "Niveau d'affinité défini à %s.", "success": "Niveau d'affinité défini à %s.",
...@@ -340,8 +348,8 @@ ...@@ -340,8 +348,8 @@
"available_three_stars": "Objets 3 étoiles disponibles" "available_three_stars": "Objets 3 étoiles disponibles"
}, },
"records": { "records": {
"title": "🇺🇸Gacha Records", "title": "Historique de voeux",
"date": "🇺🇸Date", "date": "Date",
"item": "Objet" "item": "Objet"
} }
}, },
...@@ -349,22 +357,22 @@ ...@@ -349,22 +357,22 @@
"handbook": { "handbook": {
"title": "Manuel GM", "title": "Manuel GM",
"title_commands": "Commandes", "title_commands": "Commandes",
"title_avatars": "🇺🇸Avatars", "title_avatars": "Avatars",
"title_items": "Objets", "title_items": "Objets",
"title_scenes": "Scènes", "title_scenes": "Scènes",
"title_monsters": "Monstres", "title_monsters": "Monstres",
"header_id": "🇺🇸Id", "header_id": "Id",
"header_command": "Commande", "header_command": "Commande",
"header_description": "🇺🇸Description", "header_description": "Description",
"header_avatar": "🇺🇸Avatar", "header_avatar": "Avatar",
"header_item": "Objet", "header_item": "Objet",
"header_scene": "Scène", "header_scene": "Scène",
"header_monster": "Monstre" "header_monster": "Monstre"
}, },
"index": { "index": {
"title": "🇺🇸Documentation", "title": "Documentation",
"handbook": "Manuel GM", "handbook": "Manuel GM",
"gacha_mapping": "🇺🇸Gacha mapping JSON" "gacha_mapping": "Gacha mapping JSON"
} }
} }
} }
\ No newline at end of file
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "Wiadomość wysłana.", "success": "Wiadomość wysłana.",
"description": "Wyślij wiadomość do gracza jako serwer. Jeśli nie określono celu, wysyła do wszystkich graczy na serwerze." "description": "Wyślij wiadomość do gracza jako serwer. Jeśli nie określono celu, wysyła do wszystkich graczy na serwerze."
}, },
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "Poziom przyjaźni musi być pomiędzy 0 a 10.", "range_error": "Poziom przyjaźni musi być pomiędzy 0 a 10.",
"success": "Poziom przyjaźni został pomyślnie ustawiony na %s.", "success": "Poziom przyjaźni został pomyślnie ustawiony na %s.",
......
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "Mesaj trimis.", "success": "Mesaj trimis.",
"description": "Trimite un mesaj unui jucător în calitate de server. Dacă este utilizat fără țintă, trimite mesajul către toți jucătorii de pe server." "description": "Trimite un mesaj unui jucător în calitate de server. Dacă este utilizat fără țintă, trimite mesajul către toți jucătorii de pe server."
}, },
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "Nivelul Fetter trebuie să fie între 0 și 10.", "range_error": "Nivelul Fetter trebuie să fie între 0 și 10.",
"success": "Nivelul Fetter setat ca %s.", "success": "Nivelul Fetter setat ca %s.",
......
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "Сообщение было отправлено.", "success": "Сообщение было отправлено.",
"description": "Отправляет сообщение выбранному игроку от имени сервера. При отсутствии конкретной цели, отправляет сообщение всем игрокам на сервере." "description": "Отправляет сообщение выбранному игроку от имени сервера. При отсутствии конкретной цели, отправляет сообщение всем игрокам на сервере."
}, },
"setConst": {
"range_error": "Уровень созвездия должен быть между 0 и 6.",
"level_error": "Некорректный уровень созвездия.",
"fail": "Не удалось установить уровень созвездия.",
"failed_success": "Созвездия для %s установлены на %s. Перезайдите чтобы изменения вступили в силу.",
"success": "Созвездия для %s были установлены на %s.",
"description": "Задает уровень созвездия для активного персонажа"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "Значение уровня дружбы должно быть между 0 и 10.", "range_error": "Значение уровня дружбы должно быть между 0 и 10.",
"success": "Уровень дружбы стал равен %s.", "success": "Уровень дружбы стал равен %s.",
......
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "消息已发送。", "success": "消息已发送。",
"description": "向玩家以服务器的身份发送消息。如果没有指定目标,则向服务器的全部玩家发送" "description": "向玩家以服务器的身份发送消息。如果没有指定目标,则向服务器的全部玩家发送"
}, },
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "好感度等级必须在 0-10 之间。", "range_error": "好感度等级必须在 0-10 之间。",
"success": "好感度已设为 %s 级。", "success": "好感度已设为 %s 级。",
......
...@@ -256,6 +256,14 @@ ...@@ -256,6 +256,14 @@
"success": "訊息已發送。", "success": "訊息已發送。",
"description": "向指定玩家發送訊息。" "description": "向指定玩家發送訊息。"
}, },
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": { "setFetterLevel": {
"range_error": "好感度必須在 0 到 10 之間。", "range_error": "好感度必須在 0 到 10 之間。",
"success": "好感等級已設定為 %s", "success": "好感等級已設定為 %s",
......
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