Rewards
Présentation
Rewards tient, pour chaque joueur, une file de récompenses gagnées mais pas encore récupérées. Au lieu de donner un objet ou d'exécuter une commande sur-le-champ, vous placez une récompense dans la file. Le joueur la récupère plus tard depuis un menu, lorsqu'il est en ligne et qu'il a de la place dans son inventaire. Rien n'est perdu si le joueur est hors ligne ou si son inventaire est plein au moment où la récompense est accordée.
Une récompense est un modèle que vous définissez une seule fois (une définition de récompense : objet d'affichage, lore, emplacements libres requis, actions à exécuter lors de la réclamation). L'accorder ajoute un petit enregistrement à la file ; la réclamer supprime l'enregistrement et déclenche les actions TypeWriter que vous avez liées à la définition. Comme l'effet de la réclamation est une liste d'actions TypeWriter, une récompense peut donner des objets, de l'argent, une étape de quête ou tout ce que TypeWriter peut déclencher.
La file est stockée dans un seul artifact. Lorsque l'extension MySQL fournit Redis, les serveurs qui partagent le même stockage sont invités à recharger l'artifact après chaque sauvegarde ; une récompense accordée sur un serveur peut donc être réclamée sur un autre.
Fonctionnalités
- Réclamation différée — les récompenses attendent dans la file jusqu'à ce que le joueur les réclame.
- Définitions de récompenses — un modèle réutilisable par type de récompense, avec objet d'affichage, nom, lore et exigence d'emplacements libres.
- Actions de réclamation — une réclamation déclenche n'importe quelle liste d'actions TypeWriter plutôt qu'une commande console.
- Menu de réclamation autonome — un inventaire paginé avec emplacements de récompenses, emplacement d'information, boutons de page, réclamation groupée et bouton de retour.
- Boutons intégrables — les emplacements de récompenses et un bouton de réclamation groupée peuvent être placés sur n'importe quelle page GUI via des types de boutons.
- Attributions cron —
btc_give_rewardpeut accorder une récompense au plus une fois par période cron et par joueur (récompenses quotidiennes, hebdomadaires). - Événement de réclamation — une entrée d'événement se déclenche à chaque réclamation avec l'identifiant de la récompense, les données personnalisées et les compteurs.
- Fact de comptage en attente et placeholders — utilisez la file dans des critères, des scoreboards et des menus.
- Anti-spam — un cooldown de 500 ms entre les réclamations d'un même joueur.
Installation
- Installez l'extension GUI (son nom de plugin dans la build est
GuiAndDialogs) et l'extension MySQL, toutes deux déclarées comme dépendances de Rewards. Redis n'est utilisé que pour le rafraîchissement inter-serveurs et n'est pas nécessaire sur un seul serveur. - Placez le JAR de Rewards dans
plugins/Typewriter/extensions/et redémarrez le serveur. - Installez éventuellement MiniPlaceholders pour utiliser les placeholders
rewardsdans les textes MiniMessage.
Premiers pas
Offrez une récompense de connexion quotidienne que les joueurs récupèrent depuis un menu.
- Dans le panneau web de TypeWriter, ouvrez une page statique et ajoutez un Rewards Artifact. N'en ajoutez qu'un : les placeholders et les boutons intégrés utilisent le premier qu'ils trouvent.
- Ajoutez une entrée Rewards Config (également une seule) pour ajuster les messages et la disposition du lore des récompenses.
- Ajoutez une Reward Definition. Définissez
rewardIdsurdaily_login,sourcesurdaily_login, choisissez undisplayItem, et liez dansonClaimActionsles actions qui donnent la récompense. - Créez une action Give Reward. Liez l'
artifactet lereward, activezuseCronet définissezcronExpressionsur0 0 0 * * *pour une fois par jour. Déclenchez-la depuis un événement de connexion ou un PNJ. - Créez une action Open Rewards Menu avec le même
artifact, et déclenchez-la depuis une commande ou un PNJ. - Publiez. Un joueur qui déclenche l'attribution obtient une récompense en attente ; cliquer dessus dans le menu la réclame.
Utilisez Has Pending Rewards dans un critère pour n'afficher une notification que tant que le joueur a quelque chose à récupérer.
Fonctionnement
La file ne stocke que le rewardId, l'heure d'attribution et les données personnalisées. L'objet affiché dans le menu et les actions à exécuter sont toujours lus dans la définition au moment de l'affichage ou de la réclamation. Une récompense en file dont la définition a été supprimée n'est pas affichée et ne peut pas être réclamée.
Menus
Les récompenses peuvent être affichées de deux façons qui partagent la même logique de réclamation.
Menu autonome. Open Rewards Menu ouvre son propre inventaire avec rows de 1 à 6. Les récompenses en attente remplissent rewardSlotsConfig dans l'ordre (une plage, ou une liste explicite d'emplacements lorsque useRange est désactivé). Lorsqu'il y a plus de récompenses que d'emplacements, le menu est paginé grâce aux previousPageButton et nextPageButton facultatifs. Les infoSlot, bulkClaimButton et backButton facultatifs prennent des numéros d'emplacements, un objet, un nom MiniMessage et un lore. backButton.command s'exécute en tant que joueur (sans la barre oblique initiale) ; laissez-le vide pour simplement fermer le menu. Les emplacements vides sont remplis avec backgroundItem lorsqu'il est défini. Les numéros d'emplacements vont de 0 (en haut à gauche) à 8 sur la première ligne, puis de 9 à 17, et ainsi de suite.
Boutons sur n'importe quelle page GUI. Dans un menu GUI, définissez le buttonType d'un objet sur l'un des marqueurs de Rewards. L'objet que vous configurez conserve sa position et son style ; pour les emplacements de récompenses, il est remplacé par l'objet d'affichage propre à la récompense.
| Type de bouton | Comportement |
|---|---|
rewards_button:REWARD_SLOT#<n> | Affiche la n-ième récompense en attente du spectateur (en comptant à partir de 0) ; un clic gauche la réclame. Au-delà de la dernière récompense, l'emplacement est vide. |
rewards_button:BULK_CLAIM | Un clic gauche réclame toutes les récompenses en attente pour lesquelles le joueur a de la place. |
Règles de réclamation, dans les deux modes :
- La récompense nécessite
requiredInventorySlotsemplacements vides dans l'inventaire du joueur (0 signifie aucune vérification). S'il n'y a pas assez de place, la réclamation est refusée etinventoryFullMessageest envoyé. - Une réclamation déclenche les
onClaimActionsde la définition, puis chaque entrée d'événement Reward Claimed. Une réclamation groupée va de la dernière récompense en file à la première, et déclenche l'événement une fois avec l'identifiant de récompensebulk_claim. - Les messages de réussite et de réclamation groupée proviennent de l'entrée Rewards Config. Pour les boutons intégrés, la première entrée Rewards Config trouvée est utilisée.
Le lore d'un objet de récompense est construit à partir de l'additionalLore de la définition, puis d'un séparateur et des lignes de source et d'emplacements libres, puis d'une astuce de clôture ; les libellés proviennent de l'entrée Rewards Config.
Placeholders
Expansion MiniPlaceholders rewards, utilisable dans les textes MiniMessage sous forme de balises.
| Placeholder | Renvoie |
|---|---|
<rewards_pending> | Nombre de récompenses en attente du joueur. |
<rewards_pending:rewardId> | Nombre de récompenses en attente ayant ce rewardId. |
<rewards_source:source> | Nombre de récompenses en attente dont la définition a cette source (insensible à la casse). Les récompenses dont la définition a été supprimée ne sont pas comptées. |
<rewards_claimed_total> | Nombre de récompenses que le joueur a réclamées au total. |
L'identifiant de la récompense est un argument de la balise : écrivez <rewards_pending:daily_login>, et non <rewards_pending_daily_login>. Tous les placeholders ne renvoient rien si aucun Rewards Artifact n'existe.
Entrées
7 entrées, générées depuis la source de l'extension.
Actions2
- BTC Give RewardAdds a reward to a player's pending queue (with optional cron scheduling)
- BTC Open Rewards MenuOpens the rewards queue menu for a player
Événements1
- BTC Reward Claimed EventTriggered when a player successfully claims a reward
Faits1
- BTC Has Pending RewardsReturns the count of pending rewards for a player
Artefacts1
- BTC Rewards ArtifactStores pending rewards and claim history for all players
Manifestes2
- BTC Reward DefinitionDefines a reward type that can be given and claimed by players
- BTC Rewards ConfigGlobal configuration for the rewards system (sounds, toasts, messages)
Dépannage
Le menu ne s'ouvre pas et le journal indique que l'extension GUI n'est pas installée. btc_open_rewards_menu a besoin de l'extension GUI à l'exécution. Installez-la et redémarrez. L'action ne fait aussi rien, avec un avertissement, lorsque son champ artifact est vide.
Give Reward ne fait rien. Le journal affiche un avertissement lorsque l'action n'a pas d'artifact, pas de reward, ou lorsque la définition liée a un rewardId vide. Renseignez les trois champs.
Une récompense cron n'est accordée qu'une seule fois. Avec useCron activé, l'heure de la dernière attribution est stockée par joueur et par entrée d'action. L'attribution suivante n'a lieu qu'à la prochaine correspondance de l'expression cron après ce moment. Testez avec une expression courte ou utilisez une entrée d'action différente par planning.
Une récompense en attente est invisible ou ne peut pas être réclamée. Le menu ignore les récompenses en file dont la définition est introuvable par rewardId. Ne modifiez pas le rewardId d'une définition après que des récompenses ont été accordées.
Réclamation refusée avec le message d'inventaire plein. Le joueur a moins d'emplacements vides que requiredInventorySlots. Notez que la vérification compte chaque emplacement vide de l'objet d'inventaire du joueur, y compris les emplacements d'armure et de seconde main.
Les toasts, les sons, noRewardsMessage et onClaimFailActions n'ont aucun effet. Ces champs existent dans Rewards Config et Reward Definition, mais le code de cette version ne les lit jamais. Seuls les messages de réclamation, d'inventaire plein et de réclamation groupée ainsi que la disposition du lore sont appliqués.
Les récompenses n'apparaissent pas sur un autre serveur. Le rafraîchissement inter-serveurs repose sur Redis fourni par l'extension MySQL et sur le fait que les deux serveurs lisent le même stockage d'artifact. Sans Redis, chaque serveur ne voit que sa propre copie jusqu'à son redémarrage.