Actions

SCHG How-to

Create Insta-kill and High Jump Monitors

From Sonic Retro

This tutorial/how-to will show you how to make two types of monitors, which are an insta-kill ("R"), and hi-jump monitor. The former will always kill Sonic (even if he has a shield, or is invicible or super), while the latter will cause Sonic to jump extra high for a certain time period. For this guide, I will be using the 2007 Xenowhirl Sonic 2 Discode (without the extra split). Let's begin!

Firstly, in the s2.asm file, go to the label "robotnik_monitor". Underneath that label, you should see this:

robotnik_monitor:
	addq.w	#1,(a2)
	bra.w	Touch_ChkHurt2

Change it to this:

robotnik_monitor:	;**	Credits to Hayate
	addq.w	#1,(a2)
	movea.l	a0,a1
	lea	($FFFFB000).w,a0
	jsr	(KillCharacter).l
	movea.l	a1,a0
	rts
	

Now, the hi-jump monitor is a little bit more difficult to make. For my purposes, instead of making a new monitor subtype, we will enable the hi-jump effect everytime a Tails 1up monitor is hit. Since this monitor does not do anything in 1 player mode, it is perfect for our purposes. In order for this effect to take place, we will have to make a new flag for the timing, and this flag will be called "hijump_time"

First, we will define our new flag. Near the beginning of the s2.asm file, you will find a list of variable definitions. (For newer disasms, this is in s2.constants.asm). Search for the following code, and add the flag, as shown:

; conventions specific to sonic/tails (Obj01, Obj02, and ObjDB):
; note: $1F, $20, and $21 are unused and available
inertia =		$14 ; and $15 ; directionless representation of speed... not updated in the air
hijump_time =		$1F ; <-- This guy right here is our new flag.
flip_angle =		$27 ; angle about the x=0 axis (360 degrees = 256) (twist/tumble)
air_left =		$28
flip_turned =		$29 ; 0 for normal, 1 to invert flipping (it's a 180 degree rotation about the axis of Sonic's spine, so he stays in the same position but looks turned around)
obj_control =		$2A ; 0 for normal, 1 for hanging or for resting on a flipper, $81 for going through CNZ/OOZ/MTZ tubes or stopped in CNZ cages or stoppers or flying if Tails
status_secondary =	$2B
flips_remaining =	$2C ; number of flip revolutions remaining
flip_speed =		$2D ; number of flip revolutions per frame / 256
move_lock =		$2E ; and $2F ; horizontal control lock, counts down to 0
invulnerable_time =	$30 ; and $31 ; time remaining until you stop blinking
invincibility_time =	$32 ; and $33 ; remaining
speedshoes_time =	$34 ; and $35 ; remaining
next_tilt =		$36 ; angle on ground in front of sprite
tilt =			$37 ; angle on ground
stick_to_convex =	$38 ; 0 for normal, 1 to make Sonic stick to convex surfaces like the rotating discs in Sonic 1 and 3 (unused in Sonic 2 but fully functional)
spindash_flag =		$39 ; 0 for normal, 1 for charging a spindash or forced rolling
spindash_counter =	$3A ; and $3B
jumping =		$3C
interact =		$3D ; RAM address of the last object Sonic stood on, minus $FFFFB000 and divided by $40
layer =			$3E ; collision plane, track switching...
layer_plus =		$3F ; always same as layer+1 ?? used for collision somehow

Afterwards, goto the label "tails_1up". Underneath there, you should see this:

tails_1up:
	addq.w	#1,($FFFFFEF6).w
	addq.b	#1,(Life_count_2P).w
	addq.b	#1,(Update_HUD_lives_2P).w
	move.w	#$98,d0
	jmp	(PlayMusic).l	; Play extra life music

Replace it with this:

tails_1up:				;**
	addq.w	#1,(a2)
	bset	#3,status_secondary(a1)
	move.w	#$4B0,hijump_time(a1)
	rts

What that will do is initialize a timer once the monitor is hit. You can modify the "move.w" value to any value you would like the timer to last. Lastly, in order to actually cause Sonic to jump higher, we need to modify some code for when Sonic jumps. A little ways under the label "Sonic_Jump", you should see the following code:

	move.w	#$680,d2
	tst.b	(Super_Sonic_flag).w
	beq.s	+
	move.w	#$800,d2	; set higher jump speed if super
+
	btst	#6,status(a0)	; Test if underwater
	beq.s	+
	move.w	#$380,d2	; set lower jump speed if under

Change it to this:

	move.w	#$680,d2		;***
	tst.b	(Super_Sonic_flag).w	;***
	beq.s	+			;***
	move.w	#$800,d2	; set higher jump speed if super
+
	btst	#6,status(a0)	; Test if underwater
	beq.s	+
	move.w	#$380,d2	; set lower jump speed if under
+
	btst	#3,status_secondary(a0);**test if high jump monitor was hit
	beq.s	+		;**
	move.w	#$1000,d2	;sethigher jump speed if hit

You have now created a hi-jump monitor! You can change the value at the "move.w" after the ** to any other value to set how high Sonic will jump under the influence of the high jump monitor.

EXTRA NOTE

(Addition by ThomasSpeedrunner) You may notice a bug that comes with the hi-jump monitor: once you hit it, the ability is kept for the rest of the level. So, to fix this, we must add a check. Find this bit of code:

; loc_1A10C:
Obj01_ChkShoes:		; Checks if Speed Shoes have expired and disables them if they have.
	btst	#2,status_secondary(a0)
	beq.s	Obj01_ExitChk
	tst.w	speedshoes_time(a0)
	beq.s	Obj01_ExitChk
	subq.w	#1,speedshoes_time(a0)
	bne.s	Obj01_ExitChk
	move.w	#$600,(Sonic_top_speed).w
	move.w	#$C,(Sonic_acceleration).w
	move.w	#$80,(Sonic_deceleration).w
	tst.b	(Super_Sonic_flag).w
	beq.s	Obj01_RmvSpeed
	move.w	#$A00,(Sonic_top_speed).w
	move.w	#$30,(Sonic_acceleration).w
	move.w	#$100,(Sonic_deceleration).w
; loc_1A14A:
Obj01_RmvSpeed:
	bclr	#2,status_secondary(a0)
	move.w	#MusID_SlowDown,d0	; Slow down tempo
	jmp	(PlayMusic).l

Change it to this:

; loc_1A10C:
Obj01_ChkShoes:		; Checks if Speed Shoes have expired and disables them if they have.
	btst	#2,status_secondary(a0)
	beq.s	Obj01_ChkHighJump
	tst.w	speedshoes_time(a0)
	beq.s	Obj01_ChkHighJump
	subq.w	#1,speedshoes_time(a0)
	bne.s	Obj01_ChkHighJump
	move.w	#$600,(Sonic_top_speed).w
	move.w	#$C,(Sonic_acceleration).w
	move.w	#$80,(Sonic_deceleration).w
	tst.b	(Super_Sonic_flag).w
	beq.s	Obj01_RmvSpeed
	move.w	#$A00,(Sonic_top_speed).w
	move.w	#$30,(Sonic_acceleration).w
	move.w	#$100,(Sonic_deceleration).w
; loc_1A14A:
Obj01_RmvSpeed:
	bclr	#2,status_secondary(a0)
	move.w	#MusID_SlowDown,d0	; Slow down tempo
	jmp	(PlayMusic).l

Now right below it, put in this:

Obj01_ChkHighJump:	; Checks if High Jump has expired and diasbles it if it has.
        btst    #3,status_secondary(a0)
        beq.s	Obj01_ExitChk
	tst.w	hijump_time(a0)
	beq.s	Obj01_ExitChk
	subq.w	#1,hijump_time(a0)
	bne.s	Obj01_ExitChk
	move.w  #$680,d2
	tst.b   (Super_Sonic_flag).w
	beq.s   Obj01_RmvHiJump
	move.w  #$800,d2
Obj01_RmvHiJump:
	bclr    #3,status_secondary(a0)

That fixes the infinite time bug. Now the hi-jump effect should wear off when it's supposed to!


SCHG How-To Guide: Sonic the Hedgehog 2 (16-bit)
Fixing Bugs
Fix Demo Playback | Fix a Race Condition with Pattern Load Cues | Fix Super Sonic Bugs | Use Correct Height When Roll Jumping | Fix Jump Height Bug When Exiting Water | Fix Spin Dash Code and Add Spin Dash Speeds | Fix Screen Boundary Spin Dash Bug | Correct Drowning Bugs | Fix Camera Y Position for Tails | Fix Tails Subanimation Error | Fix Tails' Respawn Speeds | Fix Accidental Deletion of Scattered Rings | Fix Ring Timers | Fix Rexon Crash | Fix Monitor Collision Bug | Fix EHZ Deformation Bug | Correct CPZ Boss Attack Behavior | Fix Bug in ARZ Boss Arrow's Platform Behavior | Fix ARZ Boss Walking on Air Glitch | Fix ARZ Boss Sprite Behavior | Fix Multiple CNZ Boss Bugs | Fix HTZ Background Scrolling Mountains | Fix OOZ Launcher Speed Up Glitch | Fix DEZ Giant Mech Collision Glitch | Fix Boss Deconstruction Behavior | Fix Speed Bugs
Design Choices
Remove the Air Speed Cap | Disable Floor Collision While Dying | Modify Super Sonic Transformation Methods & Behavior | Enable/Disable Tails in Certain Levels | Collide with Water After Being Hurt | Retain Rings When Returning at a Star Post | Improve the Fade In\Fade Out Progression Routines | Fix Scattered Rings' Underwater Physics | Insert LZ Water Ripple Effect | Restore Lost CPZ Boss Feature | Prevent SCZ Tornado Spin Dash Death | Improve ObjectMove Subroutines | Port S3K Rings Manager | Port S3K Object Manager | Port S3K Priority Manager | Edit Level Order with ASM‎ | Alter Ring Requirements in Special Stages | Make Special Stage Characters Use Normal DPLCs | Speed Up Ring Loss Process
Adding Features
Create Insta-kill and High Jump Monitors | Create Clone and Special Stage Monitors | Port Knuckles
Sound Features
Port Sonic 1 Sound Driver | Port Sonic 2 Clone Driver | Port Sonic 3 Sound Driver | Expand the Music Index to Start at $00 (Sonic 2 Clone Driver Version)
Extending the Game
Extend the Level Index Past $10 | Extend the Level Select | Extend Water Tables | Add Extra Characters | Free Up 2 Universal SSTs