Skip to content

Notices, confirmations and dialogs in v83's words - #519

Merged
neeerp merged 23 commits into
masterfrom
v83/wording-and-dialogs
Oct 18, 2026
Merged

neeerp merged 23 commits into
masterfrom
v83/wording-and-dialogs

Conversation

@neeerp

@neeerp neeerp commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Stacked on #518 (v83/trade-scrolls-guilds-ships). Please change the base to master once #518 is merged, since GitHub won't retarget it here.

A batch of smaller parity fixes, mostly HeavenClient saying and asking what v83 says and asks, each from the 2025 MapleRoyals client.

What changed

  • Notices in v83's words:
    • Cash Shop result codes; shop and storage failure codes, including the level limits.
    • SHOW_STATUS_INFO modes 2 and 6–13, which used to print "Mode: N is not handled."
    • Messenger invite results; Monster Book card lines.
    • The party, buddy, messenger and meso-drop prompts.
  • Confirmations:
    • Passing the party leadership now asks first.
    • Spending AP on MaxHP or MaxMP is ignored below level 20, then asks first.
    • A bare /w NAME is answered as v83 answers /whisper NAME.
  • World select: a world's channels open only when SERVERSTATUS_REQUEST is answered.
  • Quests and NPCs:
    • Refused quest steps are answered (UPDATE_QUEST_INFO 10) instead of hanging.
    • Say.img pages are sequenced as v83 does.
    • The NPC quest menu is grouped as v83 does, and NPC clicks follow v83's decision.
    • The dialog speaker byte is read as flags; #e text is drawn in bold until #n.
  • Skills:
    • Skill refusals now include the meso and item cost lines.
    • Shadow Meso charges its mesos (raised by Shadow Partner) and rolls damage as v83 does (L187).
  • Map limits (L182, L188): maps that forbid item use or drops (fieldLimit 0x400 / 0x400000, allowedItem) refuse them in the client with v83's lines, and on the server.
  • Invitations: messenger, buddy, trade and party invitations arrive as v83's fading cards, and a busy player answers party invites.
  • Context menu (L181): right-clicking another character opens v83's context menu.
  • Buddies: v83's buddy flags (pending requests hidden, flag 2 offline) and arrival cards.

Verification

  • New client tests: character_name, context_menu, field_limit, quest_result, skill_weapon, with many existing ones extended.
  • Harness buddy_list and the quest tests were extended.
  • This layer passes cargo fmt --check and cargo check --workspace --tests.
  • At the top of the stack the full harness suite passes (run at 45e356d, the last server commit; the commits after it change only HeavenClient). All 83 client tests pass in a debug build.

neeerp added 23 commits October 17, 2026 23:50
The failure notice for each code now uses the text v83 maps it to
(FUN_0047c17a), with its line breaks, and the default is v83's "the
request for Cash Shop has failed". Codes for coupons, gift tokens and
character transfers, which aren't served, keep the default.

Buying bag or storage slots says "You have added slots to your item
inventory." rather than the purchase text, and a sent gift shows the
count, item, recipient and price in v83's format. The server's failure
codes are documented with the texts the client now shows.
HeavenClient printed a red "Mode: N is not handled." for every mode past
5 and for mode 2. It now reads them as v83 does (FUN_00a209d4): guild
points and an item's description as grey chat lines; expired cash items,
items, seals and skills, and lines from the server, in the chat colour
v83 uses for type 0xc; a quest's extra record silently. Any other mode is
ignored, as in v83.
The Party Leader button sent the change at once. v83 first asks "Do you
wish to pass the leader position to NAME?" and sends only on Yes
(FUN_0090e41a), so HeavenClient now does the same.
Typing /w with a name and no message printed a red usage line that v83
never shows. v83's /whisper NAME refuses your own name, then checks the
name as it checks a new character's (FUN_0079fc74: 4 to 12 letters or
digits, fewer than four of 'I' and 'l') and says "Incorrect ID." in the
notice colour if it fails; otherwise it switches the chat bar to
whispering to that name. HC now does the same, filling in "/w NAME " as
its other Whisper buttons do. A bare /w does nothing: v83 goes back to
the last name whispered to, and HC keeps no list of them.
A quest step that can't give its items, or a completion that takes more
mesos than the character has, used to fail silently while the client
waited. The server now answers with UPDATE_QUEST_INFO 10 (with the quest
id) for a full inventory and 11 for missing mesos.

HeavenClient handles the other UPDATE_QUEST_INFO results as v83 does
(FUN_00959a73): 9, 11, 13 and 14 show their notices, 15 writes the expiry
line to chat, and the timer modes are ignored. For 10 it names the
inventories the step's Act.img items would go to, counting only items the
character would get by job and gender, joined with " or" as v83 joins
them, and adds the mesos clause when the step takes mesos.
v83 (FUN_00a239b7) ignores the HP and MP buttons below level 20 and, from
level 20, asks whether to go ahead before sending SPEND_AP, warning that
the character may end up weaker. The stats window now does the same;
HeavenClient used to send the request at any level without asking.
v83 sends SERVERSTATUS_REQUEST when a world is picked and builds the
channel list from the answer (FUN_006283c1), ignoring world and channel
clicks while it waits. Status 1 shows the busy-world notice over the
channels, and status 2 shows the full-world notice and leaves the list
as it was. HeavenClient opened the scroll at once and dropped the answer.

The second byte of the answer picks a busy banner for the channel list;
it is read and not drawn.
The shop result handler only knew codes 2 and 3 and stayed silent for the
rest. It now shows the notice v83 does for each code, including the level
limits (v83 prints the negated level for "under") and the low-level meso
limit, and falls back to v83's error notice for codes it doesn't know.

Storage had 0x0b and 0x0c the wrong way round on both sides. In v83, 0x0b is
having too few mesos to take an item out and 0x0c is already having a
one-of-a-kind item, so the server and client now use those values.
The party, buddy and messenger prompts, the buddy delete question, the
messenger close question and the meso drop prompt now use v83's texts.

Number boxes take a minimum, which the "higher than" notice names, as v83's
do. The meso drop box starts at 10 and refuses less, where it had let any
amount from 1 through to the server.
v83's MONSTER_BOOK_SET_CARD handler (FUN_00a081b8) prints "[card] has been
successfully recorded on the Monster Book." when a card goes into the book
and "This card is already full in the Monster Book. This card will
disappear." when the page already holds five. Both lines use chat type 0xc.
For a full page it reads only the leading byte. The client now does the same.
Both lines were checked in the GUI.
HeavenClient now checks a skill's mesos and item cost after its HP and MP,
as v83's FUN_00764256 does, and says "You don't have enough mesos to use
this skill." or names the missing item. Shadow Meso's cost grows by Shadow
Partner's y percent while that buff is on. The four cost lines share one
two-second throttle, so a second refusal within two seconds prints nothing.

The weapon check follows DoActiveSkill and its handlers (skill_weapon).
Shots need their job's weapon whatever Skill.img names, and Brandish,
Corkscrew Blow, Grenade and Poison Bomb need theirs; these say "You cannot
use this skill with the weapon you're equipped with." The held shots refuse
a wrong weapon silently. Any other mismatch with the weapon the skill names,
or the knuckle, sword and wand rules FUN_00766157 gives some pirate and
Cygnus skills, now says "This skill cannot be used with the equipped item."
Shadow Stars without enough stars has its own line, and the bullet line
gets its period back.
The messenger's invite result and invite reply now use v83's lines:
"- You have sent the invite to 'X'.", "- 'X' can't be found.", and, by the
reply's flag byte, "'X' denied the request." or "'X' is currently not
accepting chat." As in v83 (FUN_00851293, FUN_00851387), both go into an
open messenger's log and are dropped when it is closed, rather than falling
back to a red chat line.
A map whose fieldLimit has bit 0x400 lets the player use only the items its
info/allowedItem lists, and bit 0x400000 keeps items and mesos off the
ground. HeavenClient now says v83's lines for both in the skill chat colour:
"This item cannot be used here." for potions and the like, from the
inventory or a quick slot, and "You cannot drop the item here." once the
drop's questions are answered (v83 FUN_00a092fb, FUN_00a0900a, FUN_00a23de5).

Dropping an item on the ground and equipping now check v83's slot gate
first: "You can't do it right now. Catch your breath and then try again."
while alert, then "You can't do it once you're dead." Double-clicking any
item while dead says the latter. Equipping used to show a different alert
line.
The client already refuses these (L182 #15), but nothing stopped a client
that sent them anyway. The field template now keeps the map's
info/allowedItem list next to its fieldLimit and answers may_use and
may_drop the way v83 does: bit 0x400 allows only the listed items of the
kinds USE_ITEM carries, and bit 0x400000 keeps items and mesos off the
ground. USE_ITEM, item drops and meso drops refuse with an enable-actions
stat update, as they already did for dead players.
…vites

Messenger invitations, buddy requests, trade requests and party invites now
arrive as v83's FadeYesNo cards (UIInviteCard, formerly UITradeInvite):
the kind's icon and heading over "from '<name>'", O to accept and X to
decline, fading out unanswered after three minutes without sending
anything. A new card replaces one of its kind except for buddy requests.
Cards and quest-complete notices share one cascade (FadePlace), each 5 px
above the last, as v83's shared FadeYesNo list does.

As in v83, a party invite that arrives while a party card is showing is
answered with DENY_PARTY_REQUEST reason 0x16, and one carrying the
party-search flag is accepted without a card. X on a party card sends 0x17
with the receiver's name, and X on a messenger card sends the v83 decline.
The server reads reason 0x16 as busy: it tells the inviter the receiver is
taking care of another invitation and keeps that invitation pending.
Shadow Meso now costs the mesos the v83 client checks for before a throw
(FUN_00764256): its moneyCon, raised by Shadow Partner's y percent while
Shadow Partner is up. The server refuses a throw the player can't afford,
takes the mesos with the MP, and sends the new total in the same
STAT_CHANGED. Its damage cap follows the client's roll (FUN_0078df87):
ten times one and a half its moneyCon, with its x percent more on a
critical.

HeavenClient rolls Shadow Meso's damage the same way: between half and
one and a half its moneyCon, floored and times ten, its own critical in
place of the user's, a percent less for each level the mob is above the
user, and no defence subtracted.
Releasing the right button over someone else now opens UIWindow.img's
ContextMenu at the cursor, pushed back inside the view, with their name in
the top cap. The hit box is v83's (FUN_0045183b): 44 by 65 above the feet,
or 46 by 31 toward the head when prone. The rows are Personal Info, Save
Name, Trade Request, Whisper, Party Invite for leaders and the partyless,
Guild Invite for masters and Jr. Masters, and Alert GM; rows that don't
apply are left out. The menu is modal and closes before it acts, and a
press or right release outside, ESC or Enter closes it.

Trade's checks move from the info window to UITradingRoom::request so both
share them. Guild Invite runs v83's /guildinvite checks before sending
GUILD_OPERATION 5, which the server doesn't handle yet. Alert GM shows the
maintenance notice v83 gives when the server has reports off. The right
button now acts on release everywhere, as v83 does.
The client now keeps each buddy's GW_Friend flag. Requests (flag 1) stay in
the list but are hidden from the Friend tab, its counts and buddy chat;
flag 2 is always offline. A buddy coming online shows v83's pink "<name> is
logged in." card (not for guildmates), and one moving to the player's
channel shows "You're on the same ch. with <name>.", each for six seconds
with only an X. Adding, accepting and removing make v83's local checks
first, and unanswered requests are asked again after each map load unless
a request card is still up. Modes 8, 10, 0x12 and the server-text results
are read.

The server now sends unanswered requests in the list with flag 1 instead of
asking about them one at a time, so declining one still finds its entry
after the list is refreshed.
HeavenClient now plays a quest's Say.img pages the way v83's FUN_00716fe1
does. Before a completion says anything, Check/1 is tested in v83's order
(NPC, items, quests, kills); a failure shows stop/<reason>, then
stop/default, then the NPC's own d0 line, and sends nothing. At the wrong
NPC the lost pages replace stop/npc when a quest item given at the start is
gone.

Question pages (ask) have no Prev. A choice with a stop/<page>/<choice> text
is wrong: the text shows with OK and the conversation ends. Every other
choice is right, since v83 never reads answer. With stop/<page>/flip, the
lead text is a page of its own before the choices.

The yes pages now wait for the server's UPDATE_QUEST_INFO mode 8, and the
next quest opens only once they have been read to the end.

The last completion page carries v83's reward list (FUN_0071808a), built by
QuestRewards from Act/1: fixed items filtered by job and gender, meso, EXP,
and the random-item box, left out when another quest follows. #w no longer
means white. It marks text that UINpcTalk shows at once while the rest types
out. #v and #t also accept v83's "id:" form.

GUI-verified: Athena Pierce's 28223 with its reward list and yes page; Rain's
1009 quiz, both wrong and right, chaining into 1010 for a beginner; and Pio's
stop/item page.
Clicking an NPC now groups its quests the way v83 does (FUN_006d1779):
a started quest goes under "QUEST THAT CAN BE COMPLETED" only when its
completion check passes with this NPC, and otherwise under "QUEST IN
PROGRESS", so Pio's hand-in no longer looks ready before the items are
in. The groups come in v83's order (completable, available, in progress,
then ETC) and party quests 1200-1399 are left out.

Each line follows FUN_00724bac: "#d#L<n># ", the QuestInfo type in bold
red when there is one, the name, and " (Pre-completion enabled)" or
" (In Progress)" for started quests. The text layout gains #d, v83's
dialog font 10 colour #51378C, and a listed choice now starts in the
colour in effect before its #L. Bold (#e) is still drawn as normal text.
Clicking an NPC now follows v83's decision (FUN_0095fe9e, FUN_006d3392).
An NPC without quests goes to the server. When there is a quest to list,
the menu opens with the NPC's d0 greeting, and its ETC line is the NPC's
script, named by Etc/ScriptInfo.img, rather than a fixed "I have something
to tell you" for any NPC with speech. With nothing to list, an NPC with a
script goes to the server, and one without says d1 if all of its quests
are done for good, or d0, without asking the server.
v83 keeps the speaker byte of an NPC dialog and reads it as flags. 0x1
leaves out END CHAT. 0x2 shows the player's avatar and name instead of the
NPC. Either 0x2 or 0x4 moves the speaker to the right: the frame becomes
UtilDlgEx/it, ic and is, the speaker is centred at x 450, and the text,
NEXT and BACK move left. 0x8 mirrors the NPC. HeavenClient used to drop the
portrait for any nonzero byte.

HeavenClient also mirrored every NPC portrait. v83 draws the sprite as it
is unless 0x8 is set, and period footage of Cloto agrees.

A quest's flipped question is now the player's answer, said from the
right, as in v83, which gives that page speaker byte 2.
v83 picks a dialog font by colour and boldness, so "#e" makes the text
bold until "#n". HeavenClient skipped both tags and drew everything in
the regular font, so an NPC quest menu's "[Job Adv.]" type came out thin.

The text layout now records which words are bold and measures them with
the bold font's advances. GraphicsGL draws those words in the bold of
the text's font: A11M, A12M and A13M have one, and other fonts keep
their own. Checked on Oz's menu in Ereve, where the red "[Job Adv.]" is
bold and the purple quest name after it is not.
@neeerp
neeerp changed the base branch from v83/trade-scrolls-guilds-ships to master October 18, 2026 18:46
@neeerp
neeerp merged commit d034e0d into master Oct 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant