Fix evil twin, pheasant and random event graphic bugs - #1245
Open
HarleyGilpin wants to merge 11 commits into
Open
Fix evil twin, pheasant and random event graphic bugs#1245HarleyGilpin wants to merge 11 commits into
HarleyGilpin wants to merge 11 commits into
Conversation
With world.npcs.randomWalk enabled the npc tick re-applies Wander over EmptyMode, so a grabbed suspect strolled around mid-lift and wandered back out of the jail before turning north. Use PauseMode for the grab, after the jail walk and for the re-entry spawn, and turn the twin north on the same tick as the jailed animation so the face update can't be lost to the transform or the walk's leftover facing.
) Pheasants now die to a single hit from any attack style, even when the accuracy roll misses, via a new instant_death npc definition flag. Replace the chicken combat definition with pheasant-specific anims and sounds - the chicken anims belong to the reworked chicken rig, which the pheasant model never got.
The instant_death npc param only ever applied to pheasants, so match on the id directly instead. Pheasants also can't deal damage: Damage.maximum reads max_hit_melee off the npc definition ahead of the combat definition's range, so the inherited value had to go for the combat definition's target hit of 0 to apply.
Event heralds spawned in with no graphic at all, and the two places that did play one flagged it on the npc immediately before removing it. NPCs.remove hides an npc for the rest of the tick, so the update task drops every visual set on it that tick and the puff was never sent. Adds shared eventHerald/poof helpers - the vanish graphic is spawned on the npc's tile so removal can't swallow it - and routes every event's herald spawn and despawn through them.
…n instance Movement subtracted the player's instance offset from both ends of a move. On the teleport into an instance the from tile is still real map, so it was offset into a tile the player was never on and nothing they actually left fired its exit handler: the barrows overlay stayed up and the mort myre swamp decay timer kept running for the whole event. Each end is now mapped on its own, only when it is inside the block of regions instances are allocated from. Fight cave relied on the old asymmetry to clean up: its exit tile is inside tzhaar_fight_cave_multi_area, so leaving on foot is not an area change and never was one - the instance end used to be compared against a meaningless tile. It now tears the instance down in leave, and the exit handler covers the logout path it always did. Swamp decay also had no exit handler at all and checked immunity before the area, so a player carrying a blessed sickle out of the swamp kept the timer for the rest of their session.
World.shutdown despawned every player without marking them as leaving the world, so area exit handlers ran their walked-out branch instead. Fight cave cleared the wave and left the player on an instance tile, and the shutdown save persisted both, so a restart mid-cave cost the run and logged the player back in inside a dead instance. Godwars killcounts and greegrees went the same way. Sets logged_out before the despawn, which is what every one of those handlers already checks for a logout.
Both trolls fell through to the default chathead expressions, which are the reworked human head set (9807+, skeleton 2165). Their chathead model 3790 is a 2005 troll head rigged to the pre-rework skeleton, so those frames tore it apart mid-dialogue. Trolls belong to the old expression set (554-617, skeleton 82), which void already exposes as the "old" dialogue family and already uses for other pre-rework models such as frogs, clay golems and Thurgo. Same rig mismatch as the pheasant defend animation earlier in this branch, from the other direction.
The next post was drawn from all five, so it could land on the one just tagged and read as the event having ignored the tag. The post that was just lit is now excluded from the draw. Tagging was also silent. The 634 cache has the event's audio at 2278 (pillar tag) and 2279-2283 (one tone per pillar); tagging plays the first and lighting a post plays that post's tone, so the flashing post can be found by ear.
The pan ran at the slowest camera rate the codebase uses and was held for ten ticks, so it was still creeping when control came back. Doubles the constant speed and halves the hold, which is what the hold was before the pan was slowed down. The lock itself was already there - the delay attribute makes every input handler drop the player's clicks - but nothing asserted it, so the cutscene test only proved that discarded input never resurfaces. It now checks the lock is held mid-pan and released on the tick the camera resets, which fails if the hold changes in either direction. A queue can't be used for this: ActionQueue.noInterrupt() refuses to run anything while a dialogue is open and the servant's hint line stays up for the whole pan. Noted in showSpot so it isn't retried.
The lock was correct for its duration - a minimap click decodes to the same Walk instruction as a map click and was already dropped for every tick of the hold - but it ended on the same tick as clearCamera, so a click made during the pan could land on the frame the camera snapped back. The pan now stays locked one tick past the reset. The pan's ease-in term was also left behind when the hold was halved. Both camera terms are per-tick rates, so acceleration scales with the hold the same way speed does; at 10 the camera was still travelling when the reset arrived, which is what made the cutscene look like it had handed control back early. New test sends a minimap walk on every tick of the pan and asserts the player hasn't moved, which is what none of the existing cutscene tests covered.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1227. Replaces #1233, whose branch picked up duplicate commits from an upstream rebase.
Evil Twin
With
world.npcs.randomWalkon, the npc tick re-appliesWanderoverEmptyModeevery tick, so a grabbed suspect strolled around mid-lift and wandered back out of the jail while the face-north flag was applied. WorldTest forcesrandomWalkoff, which is why no test caught it. The grab, the drop at the jail and the re-entry spawn now usePauseMode, and the twin turns north on the same tick as the jailed animation, a tick afterclearTransform, so the face update can't be lost to the transform or the walk's leftover facing.New test runs the grab with
randomWalkenabled and asserts the twin ends on the jail tile facing north.Freaky Forester
Target.damageLimitModifiersalongsidedamage_capandimmune_death.Damage.maximumreadsmax_hit_meleeoff the npc definition ahead of the combat definition's range, so the inheritedmax_hit_melee = 10had to go for the combat definition'starget_hitof 0 to apply.New test forces every accuracy roll to fail and asserts one swing kills the pheasant and drops the raw bird; it fails without the fix.
Random event puff of smoke
Adds a shared
eventHeraldfor the spawn andpooffor the removal, and routes every event through them.poofspawns the graphic on the npc's tile rather than flagging it on the npc, the wayImpalready does, so removal can't swallow it.New test asserts the graphic is still flagged on the tick the npc reaches clients, since the spawn is queued a tick ahead of that.
Area exit handlers on the way into an event
Reported after the above: being taken by a random event out of Mort Myre kept the swamp decay running, and out of the barrows crypts kept the barrows overlay on screen for the whole event.
Movement.movesubtracted the player'sinstance_offsetfrom both ends of a move. The six events that build an instance set that offset before the teleport that carries the player in, so thefromtile - still real map - was offset into a tile the player was never on, and no area they actually left fired its exit handler. Each end is now mapped on its own, and only when it is inside the block of regions instances are allocated from.Fight cave was relying on that asymmetry. Its exit tile sits inside
tzhaar_fight_cave_multi_area, so leaving on foot is not an area change and never was one; the instance end just used to be compared against a meaningless tile. It now tears the instance down inleave, and the exit handler keeps the logout path it always had.Swamp decay had no exit handler at all and checked immunity ahead of the area, so a player carrying a blessed sickle out of the swamp kept the timer, the message and the shield graphic for the rest of their session however they left.
New tests kidnap a player out of the barrows crypts and out of Mort Myre and assert the overlay closes and the timer stops; both fail without the fix.
Fight cave progress lost on shutdown
World.shutdowndespawned every player without marking them as leaving the world, so every area exit handler took its walked-out branch. Fight cave clearedfight_cave_waveand left the player standing on an instance tile, and the shutdown save persisted both - a restart mid-cave cost the run and logged the player back in inside a dead instance. Godwars killcounts and greegrees were dropped the same way.logged_outis now set before the despawn, which is the flag all of those handlers already check. Logging out normally was never affected;AccountManager.logoutsets it.New test takes a player into the cave, shuts the world down and asserts the wave survives and the player is back on real map; it fails without the fix.
Flippa and Tilt chatheads
Both pinball trolls had no
dialoguekey, soNPCDialoguefell through to the default expression names. Those are the reworked human chathead set (expression_neutral1= 9807 onwards, skeleton 2165); Flippa and Tilt share chathead model 3790, a 2005 troll head rigged to the pre-rework skeleton 82, so the frames tore it apart mid-dialogue.They now use the
oldfamily (554-617, skeleton 82), which is the same set void already gives other pre-rework models - frogs, clay golems, etc.Closes #1113
Pinball posts
The next post was drawn from all five, so it could land on the post that had just been tagged - which reads as the event having ignored the tag rather than as a new target. The post that was just lit is now excluded from the draw.
Tagging was also silent. The 634 cache carries this event's audio: 2278 is the pillar tag and 2279-2283 are one tone per pillar.
Tests now tag whichever post is flashing rather than assuming it never moves, plus a new case asserting the target never repeats across eight tags.
Evil Bob fishing spot pan
Sped up the camera pane and fixed a camera lock bug caused by moving after the last tick of the camera pane cutscene.