avm1: Set target clip to None if target is an undefined object

SetTarget currently sets the target clip to the base clip if the
target passed to tellTarget() is an undefined object. This causes
goto's to run on the base clip in Ruffle, when Adobe Flash Player
does not run the goto's at all.

Fixes #12389 and #12390
This commit is contained in:
Abiel Deneke 2023-08-18 20:57:50 -05:00 committed by Nathan Adams
parent 4e6e28f78c
commit 0ed447b428
5 changed files with 16 additions and 6 deletions

View File

@ -1981,9 +1981,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
return self.set_target(&target); return self.set_target(&target);
} }
Value::Undefined => { Value::Undefined => {
// Reset. self.set_target_clip(None);
let base_clip = self.base_clip();
self.set_target_clip(Some(base_clip));
} }
Value::Object(o) => { Value::Object(o) => {
if let Some(clip) = o.as_display_object() { if let Some(clip) = o.as_display_object() {
@ -2012,7 +2010,10 @@ impl<'a, 'gc> Activation<'a, 'gc> {
} }
}; };
let clip_obj = self.target_clip_or_root().object().coerce_to_object(self); let clip_obj = self
.target_clip_or_base_clip()
.object()
.coerce_to_object(self);
self.set_scope(Scope::new_target_scope( self.set_scope(Scope::new_target_scope(
self.scope(), self.scope(),
@ -2925,6 +2926,12 @@ impl<'a, 'gc> Activation<'a, 'gc> {
.unwrap_or_else(|| self.base_clip().avm1_root()) .unwrap_or_else(|| self.base_clip().avm1_root())
} }
/// The current target clip of the executing code.
/// Actions that affect the base clip after an invalid `tellTarget` will use this.
pub fn target_clip_or_base_clip(&self) -> DisplayObject<'gc> {
self.target_clip().unwrap_or_else(|| self.base_clip())
}
/// Obtain the value of `_root`. /// Obtain the value of `_root`.
pub fn root_object(&self) -> Value<'gc> { pub fn root_object(&self) -> Value<'gc> {
self.base_clip().avm1_root().object() self.base_clip().avm1_root().object()

View File

@ -1,3 +1,6 @@
Target not found: Target="dummy" Base="_level0.mc" Target not found: Target="dummy" Base="_level0.mc"
/tellTarget('dummy') { gotoAndStop(n); } /tellTarget('dummy') { gotoAndPlay(n); }
pass
/tellTarget(undefined) { gotoAndPlay(5); }
/tellTarget(undefined) { gotoAndPlay(n); }
pass pass

View File

@ -1 +1 @@
num_frames = 1 num_frames = 5