Skip to content

Megaphones, chalkboards, teleport rocks and the pet name tag - #522

Merged
neeerp merged 11 commits into
masterfrom
v83/megaphones-rocks-name-tag
Oct 18, 2026
Merged

neeerp merged 11 commits into
masterfrom
v83/megaphones-rocks-name-tag

Conversation

@neeerp

@neeerp neeerp commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Stacked on #521 (v83/pets-summon-food). Please change the base to master once #521 is merged, since GitHub won't retarget it here.

Cash items, mostly (L179), plus the pet name tag (L159) and skill books (L189).

What changed

  • Megaphones:
    • The server reads the kind from the item id as v83 does.
    • The plain megaphone (level above 10) reaches the speaker's channel. Super, item and triple megaphones reach the whole world, through a new WorldAction::Broadcast.
    • HeavenClient puts megaphone lines in the chat log with v83's colours and channel tags.
    • The megaphone dialogs follow v83: the text prompt for the plain one; modal windows with the whisper checkbox for the super and triple; and the item megaphone's window, which takes a dropped item.
    • The checks run in v83's order. The triple megaphone has its samples popup and Preview.
  • Chalkboards:
    • Holding one up shows the note (CHALKBOARD 164) to the holder and the map, and SPAWN_PLAYER carries it to later arrivals.
    • It follows the holder across maps, except into the Free Market rooms.
    • HeavenClient draws the ChatBalloon adboard and its close button.
  • Teleport rocks:
    • Characters keep 5 maps for the regular rock and 10 for the VIP one, in a new teleport_rocks table.
    • TROCK_ADD_MAP adds and removes maps.
    • The rock warps to a kept map or to a character by name, with v83's refusal reasons (MAP_TRANSFER_RESULT).
    • HeavenClient has the v83 map list window. Notices raised from a window now hand the focus back to it.
  • Pet name tag (L159): renames the first pet out. The server sends 172 to the owner and the map, and HeavenClient has the name prompt.
  • Skill books (L189): double-clicking a skill or mastery book now sends USE_SKILL_BOOK, as v83's inventory window does, instead of USE_ITEM.

Not covered

  • Maple TV.
  • Dragging the megaphone windows.

Verification

  • New harness tests: megaphones, chalkboard, teleport_rocks; pets extended with the rename.
  • New client tests: megaphones, chalkboard, teleport_rock; pets extended.
  • Megaphones, chalkboards and skill books were checked in the client on Xvfb.
  • 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 11 commits October 18, 2026 08:43
The USE tab's double-click sent skill and mastery books (228xxxx, 229xxxx)
as USE_ITEM, which the server does not answer with a book result. v83's
inventory window sends them as USE_SKILL_BOOK (FUN_00a0a1b2, called from
the same chain as pet food), which the hotkey path already did.
USE_CASH_ITEM now uses megaphones (507xxxx), reading the kind from the
item id's thousands digit as the v83 client does. A plain megaphone needs a
level above 10 and its line (BROADCAST_MSG type 2) goes to every player on
the speaker's channel. The super, item and triple megaphones (types 3, 8 and
10, with the zero-based channel and the ear byte) go to the whole world,
the speaker included. Every line is at most 60 bytes and is sent as
"<name> : <text>", which the client splits on " : "; the item megaphone
carries the item the speaker picked. One exclusive inventory operation uses
the megaphone up, and anything refused, Maple TV included, only unlocks the
client.

The client actor hands the line to the world directory through the new
WorldAction::Broadcast, and BroadcastScope gains Channel so the directory
can pick the speaker's channel.
USE_CASH_ITEM now handles the pet name tag (5170000). It carries the new
name after the item id, and renames the first pet out, as the v83 client
targets it. The server takes the tag and re-sends the pet's item in one
exclusive inventory operation, then sends 172 (cid, index, name, name tag
style) to the owner and the map. The owner needs the 172 as well: the
client hears pet commands by the pet's name, and 172 is what changes it.
Without a pet out, or with a name the client would not have sent (outside
4 to 12 bytes, padded, or with control characters), the server only
unlocks the client with an empty stat change.

The rename goes through the pets' change list as PetChange::Renamed, so
the client actor sends 172 alongside the other pet packets. The harness
pets test renames the Baby Tiger and checks that the owner and a watcher
see the name, and that it is kept after a relog.
Double-clicking the pet name tag in the Cash tab now walks through the v83
dialogs. A pet that already has a name of its own asks whether to change
it, then the name prompt takes up to 12 bytes. pets::check_name follows the
v83 checks: the name is trimmed, under 4 bytes asks again, control
characters are refused as cursing, curse words are starred out, and the
kind's own name (in any case) or the pet's current name is not available.
A last Yes/No sends USE_CASH_ITEM with the name under the WAIT lock and
plays UseShopItem. With no pet out the tag does nothing, as in v83.

172 sets the pet's name and its label. The name tag style byte is read and
ignored, so the label stays plain.
USE_CASH_ITEM now handles the chalkboard (537xxxx). Its note, 1 to 40
bytes as the v83 client allows, is kept on the player (not saved) and
their field avatar, and CHALKBOARD (164) shows it to the holder and the
map. The holder needs the 164 too: the v83 client only lets them click the
board away once it has been told the board is up. An empty stat change
then unlocks the client, since the chalkboard isn't used up.
CLOSE_CHALKBOARD (0x32) puts the board away for the holder and the map.

SPAWN_PLAYER now writes the board, so later arrivals see it. It comes
along to the next map, where the holder's client is told again, but a map
where shops open (the Free Market rooms) puts it away, as the client does
there. The harness's SPAWN_PLAYER decoder reads the board, and the
chalkboard test covers a watcher, a map change, closing, and the Free
Market.
A character now keeps maps for the teleport rocks: five for the regular
rock and ten for the VIP one, saved in a new teleport_rocks table and
written into SET_FIELD's character data, with 999999999 for the empty
slots. TROCK_ADD_MAP (0x66) keeps the player's map or drops one and
answers with the new list in MAP_TRANSFER_RESULT (0x2A, result 3 or 2).
Maps the v83 client wouldn't offer (Maple Island, event maps), maps
whose fieldLimit forbids rocks, a full list and a map already kept are
refused with result 10.

The rock is used through USE_CASH_ITEM, to a kept map or to a character
by name. A name goes through the world directory to the character's
client actor on the same channel, which answers with where they stand;
the user lands on the spawn point nearest them. A refusal is
MAP_TRANSFER_RESULT with the v83 reason (6 not found, 9 the same map,
11 Maple Island under level 7, 8 the rest: a map not kept, a dead user,
fieldLimit 0x40 or 0x2 on either end, another continent for the regular
rock, a forcedReturn map off Maple Island) and an empty stat change, as
42 doesn't unlock the client. Otherwise an exclusive inventory operation
takes one rock and the user is warped.

warp_to_spawn_point is split out of warp for the trip to a character.
Unit tests cover the lists, each refusal and both kinds of trip, and the
teleport_rocks harness test keeps a map, rocks to it and to a watcher,
is refused twice, and finds the list kept after a relog.
HeavenClient now reads BROADCAST_MSG types 2, 3, 8, 9 and 10 as v83 does
and puts each megaphone in the chat log with v83's colours: blue on a pale
blue strip for the plain megaphone, purple on pink for super and triple
megaphones, brown on yellow for item megaphones. Every row but the plain
megaphone's starts with the channel tag from UIWindow.img/Megaphone (ch0
with the ear, ch1 without) and the two-digit channel, so the first row
leaves room for it. An item megaphone puts [item name] after the speaker's
name, and a triple megaphone's later lines take the first line's name.
Megaphones are not heard on event maps.

The client still can't use a megaphone; its dialogs come next.
The client now draws the board over anyone holding a chalkboard, as v83
does with the ChatBalloon.img adboard style. The note wraps by character
at 14 tiles, a one-line note gets an odd tile count so the arrow is
centred, and the board floats over the head with its arrow just right
of the feet. Another player's note is trimmed, has its curse words
masked and is cut to 40 bytes, both when they spawn and when packet 164
changes it.

The player's own board has a close button that needs both the press and
the release on it, left button only, and an open mini room blocks it.
Closing sends packet 50 and says "The chalkboard has closed."; the board
stays until the server takes it down. A press whose release lands on a
window, or is lost to a focus change, is forgotten, so hovering the
button later does not close the board. The board follows the player
across map changes, except into a map that allows personal shops, where
it is dropped with "You cannot use the chalkboard here."

Double-clicking a chalkboard in the Cash tab asks for a note and sends
it with the cash item packet. A blank or cancelled note sends nothing.
An open mini room answers "Not available", and a personal shop map
answers "You can't use it here in this map."
Double-clicking a teleport rock in the Cash tab now opens the v83 map
list from UIWindow.img/Teleport, centred and modal. It shows the kept
maps by name, a linked map under its source's name, five rows at a time
with a scroll bar on the VIP rock, and counts them as [used/size]. The
client reads both lists from the character data and replaces one when
packet 42 answers with result 2 or 3.

ADD MAP asks before sending packet 102 for the current map, unless the
list is full, already has it, or the map is on Maple Island or an event
map. DEL. MAP asks before dropping the selected map. MOVE asks before
using the rock on the selected map, or uses it at once on a typed name
once the name is valid and isn't the player's own. Enter is MOVE and
Escape closes the window, which closes before the rock is used and plays
the shop sound once the request goes out. A refusal on packet 42 shows
its notice, naming the character for result 6. The rock isn't offered
on a map whose fieldLimit forbids teleporting, and like the chalkboard
it waits for an earlier request with "Other requests are in process."

Notices raised from a window now hand the focus back to it when they
close: the game state keeps the windows a focused one opened over, and
a dialog under its notice stays modal. The name field gives up the keys
for a notice and takes them back afterwards if it had them.
Double-clicking a megaphone in the Cash tab now opens its v83 dialog
instead of doing nothing. The plain megaphone asks for a line through the
text prompt. The super and triple megaphones open a modal window on the
Megaphone and ArtMegaphone art, with the whisper-icon checkbox. The triple
megaphone asks before sending with an empty line, and its Preview button
writes the lines to the player's own chat log. The item megaphone opens a
window that leaves the game playable; an item dropped on it from the
inventory shows in its well with its name and tooltip.

The checks run in v83's order, after the dialog closes: an empty line
is dropped, then cursing, a level of 10 or below and an over-long line are
refused with v83's notices. Util/Megaphones.h holds these checks and the
kind decoding, with tests. The item megaphone checks its own request lock
and asks before going without an item.

The Special Character button does nothing yet, the windows can't be
dragged, and Enter reaches the item megaphone only while its field has
focus.
The triple megaphone's Special Character button now opens the item's
samples from Item.nx in a modal popup, placed and drawn as v83 does. A
sample replaces all three lines, with anything past ASCII turned into '?'
as the ANSI code page would. "CREATE NEW" empties the lines. Escape,
Enter, or a click outside closes the popup without changing anything.

Preview now prints v83's header line and then the lines up to the last one
written, empty ones included, in the grey of chat type 0x15 with indented
wrapped rows. With every line empty it prints nothing; before, it raised a
notice.

Both megaphone windows now toggle the whisper checkbox when the button
comes up after a press on it, even outside the window, instead of on the
press. Tab moves between the triple megaphone's lines. The item
megaphone's item name is now left-aligned in its bar and cut to fit with
"..".
@neeerp
neeerp changed the base branch from v83/pets-summon-food to master October 18, 2026 18:46
@neeerp
neeerp merged commit 65238d4 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