;THE SPRITE NUMBER TO USE FOR THE THROWN VIAL CAN BE FOUND BELOW WITHIN THE CODE.  You can't possibly miss it.

YDisp:
db $F4,$F0,$00,$F4,$F1,$01,$F4,$F0,$00

Tilemap:
db $00,$80,$A0,$00,$80,$A2,$86,$84,$A4

TileProp:
db $2B,$4B,$4B,$6B,$0B,$0B

EndLoopCount:
db $00,$00,$FF

SlopeEor:
db $08,$F8,$02,$03,$04,$04,$04,$04,$04,$04,$04,$04

FreeRAM:	;FreeRAM to use for the tilemap if the bit is set.  It must be a 24-bit address!
db $7F,$88,$00


;Major thanks to imamelia for the original rip of Dry Bones, which this sprite is based off of.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; init routine
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print "INIT ",pc

JSR FacePlayer	; face the player initially

LDA $7FAB10,x	;
AND #$04	; store the extra bit to a misc. sprite table
STA $1510,x	;

RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; main routine wrapper
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print "MAIN ",pc
PHB
PHK
PLB
JSR DryBonesMain
PLB
RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; main routine
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DryBonesMain:

LDA $14C8,x	;
CMP #$08	; if the sprite is in normal status...
BEQ NormalRt	; run the standard code
ASL $15F6,x	; if not...
SEC		; set bit 7 of $15F6,x (sprite palette and GFX page) so that the sprite graphics will be Y-flipped
ROR $15F6,x	; (actually, it doesn't matter, since $15F6,x is never referenced anyway)
JMP SkipToGFX	; and go directly to the GFX routine

NormalRt:		;


LDA $9D			; if sprites are locked...
ORA $163E,x		; (not sure what this does...$163E,x isn't referenced or modifed anywhere else)
BEQ Continue1		;
JMP Skip1			;

Continue1:

LDY $157C,x		;
LDA SlopeEor,y		; not sure what the purpose of this is...
EOR $15B8,x		; EOR it with the value of the slope the sprite is standing on
ASL			;
LDA SlopeEor,y		; now load the data itself
BCC StoreXSpeed		; if bit 7 of the data/slope EOR was set, store the X speed directly
CLC			;
ADC $15B8,x		; if not, add the value from the slope first
StoreXSpeed:		;
STA $B6,x		;

LDA $1540,x		; if the stun timer is set...
BNE ZeroXSpeed		; set the sprite X speed to 0
TYA			; if not...
INC A			; transfer the sprite direction to A and then increment it
AND $1588,x		; AND it with the sprite direction status
AND #$03		; if the sprite is touching a wall...
BEQ NoZeroXSpeed	;
ZeroXSpeed:		;
STZ $B6,x		;
NoZeroXSpeed:		;

LDA $1588,x		;
AND #$08		; if the sprite is touching the ceiling...
BEQ NoZeroYSpeed	;
STZ $AA,x		; set the sprite Y speed to 0
NoZeroYSpeed:		;

JSR SubOffscreenX0	; offscreen processing
JSL $01802A		; update sprite position         


LDA $1540,x	; $1540,x is *also* used as a throw timer for the bone-throwing Dry Bones.
BEQ NoThrow	; Its purposes are differentiated by $1534,x, which is nonzero if the sprite is crumbled.
CMP #$01	; if the throw timer has dropped to 1...
BNE NoBone	;

JSR ThrowBone	; throw a bone (technically, I could just JSL to $03C44E, but I might as well disassemble that too)

NoBone:		;

LDA #$02	; set the throwing frame
STA $1602,x	;
JMP Skip1	; and skip the speed-setting etc.

NoThrow:

LDA $1588,x		;
AND #$04		; if the sprite is not on the ground...
BEQ NotOnGround		; skip the next part of code

JSR SetSomeYSpeed	;
JSR SetAnimationFrame	;

LDA $1510,x		;
BEQ Skip2		;
STZ $C2,x		;
BRA NoUpdate		;

Skip2:			;

LDA $1570,x		;
AND #$1F		; every 80 frames...
BNE NoUpdate		;

JSR FacePlayer		; turn to face the player
BRA NoUpdate

NotOnGround:

STZ $1570,x		;
LDA $1510,x		;
BEQ NoUpdate		; skip the next part if the sprite acts like 30

LDA $C2,x		;
BNE NoUpdate		;
INC $C2,x		;

JSR FlipSpriteDir		; flip the sprite's direction
JSL $018022		; update sprite X position without gravity...
JSL $018022		; twice

NoUpdate:

; removed sprite number check:
;CODE_01E57B:        B5 9E         LDA RAM_SpriteNum,X
;CODE_01E57D:        C9 31         CMP.B #$31
;CODE_01E57F:        D0 17         BNE CODE_01E598

LDA $1510,x		;
BEQ MaybeResetThrowTimer	;


MaybeResetThrowTimer:

LDA $1570,x		;
CLC			;
ADC #$40		; check the animation frame
AND #$7F		; if it is not 40 or C0...
BNE Skip1			; don't reset the throw timer

LDA #$1F			;
STA $1540,x		; time until the Dry Bones throws another bone

Skip1:
     
JSR Interact	; player interaction code
JSL $018032	; interact with other sprites
JSR MaybeFlip	;

SkipToGFX:

JSR DryBonesGFX	; draw the sprite

Return00:		;
RTS		;

Interact:

JSR ImStickingTheInteractionRoutineElsewhereForReadability


NoContact:
Return01:
RTS

MaybeFlip:	; ripped from $019089

LDA $157C,x	;
INC		;
AND $1588,x	; if the sprite is touching an object in the direction that it is facing...
AND #$03	;
BEQ Return01	;

JSR FlipSpriteDir	; flip it

RTS		;

FlipSpriteDir:	; ripped from $019098

LDA $15AC,x	; if the turn timer is already set...
BNE Return01	; return

LDA #$08		;
STA $15AC,x	; set the turn timer
LDA $B6,x	;
EOR #$FF		; invert the sprite X speed
INC		;
STA $B6,x		;
LDA $157C,x	;
EOR #$01		; flip the sprite direction
STA $157C,x	;

RTS

FacePlayer:

JSR SubHorzPos	;
TYA		;
STA $157C,x	;
RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; graphics routine
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DryBonesGFX:

LDA $157C,x	;
PHA		; preserve the sprite direction
LDY $15AC,x	;
BEQ JustDraw	;
CPY #$05	; if the turn timer is 05 or greater...
BCC JustDraw	;
EOR #$01	; flip the sprite direction before drawing it
STA $157C,x	;

JustDraw:	;

JSR MainGFXRt	;

PLA		;
STA $157C,x	;

MainGFXRt:

; removed sprite number check:
;CODE_03C3DA:        B5 9E         LDA RAM_SpriteNum,X       
;CODE_03C3DC:        C9 31         CMP.B #$31                
;CODE_03C3DE:        F0 CE         BEQ CODE_03C3AE           

JSL $20CA4F	;



	LDA $7FAB10,x
	AND #$04
	BNE Dynamic

	LDA.b #Tilemap
	STA $0D
	LDA.b #Tilemap>>8
	STA $0E
	LDA.b #Tilemap>>16
	STA $0F
	BRA DoneWithDrawingType
Dynamic:
	LDA FreeRAM
	STA $0F
	LDA FreeRAM+1
	STA $0E
	LDA FreeRAM+2
	STA $0D

DoneWithDrawingType:


LDA $15AC,x	;
STA $05		; save the turn timer in scratch RAM

LDA $157C,x	;
ASL		;
ADC $157C,x	; sprite direction x 3 -> $02
STA $02		;

PHX			; preserve the sprite index
LDA $1602,x		; current frame
PHA			;
ASL			; x2...
ADC $1602,x		; x3
STA $03			; frame x 3 -> $03
PLX			; get the frame into X
LDA EndLoopCount,x	; set the number at which the loop will end
STA $04			;

LDX #$02		; 2 or 3 tiles to draw, depending on whether or not the sprite is throwing a bone        

GFXLoop:

PHX		; preserve the tilemap index
TXA		;
CLC		;
ADC $02		; add the value from the direction to the index
TAX		;
PHX		;
LDA $05		; if the turn timer is set...
BEQ NoIncIndex1	;
TXA		;
CLC		;
ADC #$06	; increment the index by 6
TAX		;
NoIncIndex1:	;

LDA $00		; base X position
;CLC		;
;ADC XDisp,x	; set the X displacement of the tile
STA $0300,y	;

PLX		; set the tile properties depending on the sprite direction
LDA TileProp,x	; palette, GFX page, and X flip
ORA $64		; add in sprite priority settings
STA $0303,y	; set the tile properties

PLA		;
PHA		; the tilemap index from before
CLC		;
ADC $03		; add the value from the frame
TAX		;

LDA $01		; base Y position
CLC		;
ADC YDisp,x	; set the tile Y displacement
STA $0301,y	;

PHY
TXY
LDA [$0D],y	; set the tile number
PLY
STA $0302,y	;

PLX		; the index from the beginning, the tile count
INY #4		; increment the OAM index
DEX		; and decrement the tile counter
CPX $04		; if the counter has dropped to 00 or FF (depending on whether we're drawing 2 tiles or 3)...
BNE GFXLoop	;

PLX		; pull back the sprite index
LDY #$02	; the tiles are 16x16
TYA		; and...well, this just assumes that we drew 3 tiles
JSL $81B7B3	; finish off the OAM write

RTS		;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; bone-throwing subroutine, ripped from $03C44E
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Potions:
db $02,$06,$02,$06,$04,$06,$02,$02
NoSpawn2:
RTS

ThrowBone:

;LDA $15A0,x	; if the sprite is offscreen horizontally...
;ORA $186C,x	; or vertically...
;BNE NoSpawn	; don't throw a bone



JSL $02A9DE
BMI NoSpawn2

LDA $E4,x
STA $0C
LDA $D8,x
STA $0D
LDA $14E0,X
STA $0E
LDA $14D4,x
STA $0F
LDA $157C,X
STA $0B


LDA $1594,x	;Potion type to throw
BNE ONoesWeHaveDiedThrowTheLastDitchPotion

PHX

JSL $01ACF9	;Determine the potion to throw
LDA $148D
EOR $148E
CLC
ADC $80
CLC
ADC $7E
AND #$07
TAX
LDA Potions,X
STA $05
BRA WeHaveNotYetMetOurMaker

ONoesWeHaveDiedThrowTheLastDitchPotion:
PHX
LDA #$05
STA $05
WeHaveNotYetMetOurMaker:

TYX
LDA #$01			
STA $14C8,x
LDA #$2F
STA $7FAB9E,x			;SPRITE NUMBER FOR THE THROWN VIAL.  LOOK HERE THIS IS THE SPRITE NUMBER FOR THE THROWN VIAL DO YOU SEE ME LOOK OVER HERE NOW THIS IS WHAT YOU'RE LOOKING FOR OVER HERE HEY YOU LISTEN TO ME I'M RIGHT HERE.
JSL $07F7D2
JSL $0187A7
LDA #$08
STA $7FAB10,x

;Store it to Mario's position.
LDA $0C
STA $E4,x
LDA $0E
STA $14E0,x
LDA $0D
STA $D8,x
LDA $0F
STA $14D4,x

LDA #$C0
STA $AA,x

LDA $05	;Potion type to throw
CMP #$05
BEQ ThrowAtMario

LDA $0B
BEQ ThrowTheOtherWayDummy
LDA #$DF
STA $B6,x
BRA DontThrowTheOtherWayDummy
ThrowTheOtherWayDummy:
LDA #$20
STA $B6,x
BRA DontThrowTheOtherWayDummy

ThrowAtMario:
LDA $7B
STA $B6,x

DontThrowTheOtherWayDummy:

LDA $05
STA $1528,x

STX $00
PLX
LDA $7FAB10,x
PHX
LDX $00
AND #$04
BNE MakeDynamicPotion
BRA ActuallyDont
MakeDynamicPotion:

LDA $7FAB10,x
ORA #$04
STA $7FAB10,x
ActuallyDont:
PLX
NoSpawn:
RTS		;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; miscellaneous standard subroutines
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Table1:              db $0C,$1C
Table2:              db $01,$02
Table3:              db $40,$B0
Table6:              db $01,$FF
Table4:              db $30,$C0,$A0,$C0,$A0,$F0,$60,$90,$30,$C0,$A0,$80,$A0,$40,$60,$B0
Table5:              db $01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$00,$01,$FF

SubOffscreenX0:
LDA #$00
;BRA SubOffscreenMain
;SubOffscreenX1:
;LDA #$02
;BRA SubOffscreenMain
;SubOffscreenX2:
;LDA #$04
;BRA SubOffscreenMain
;SubOffscreenX3:
;LDA #$06
;BRA SubOffscreenMain
;SubOffscreenX4:
;LDA #$08
;BRA SubOffscreenMain
;SubOffscreenX5:
;LDA #$0A
;BRA SubOffscreenMain
;SubOffscreenX6:
;LDA #$0C
;BRA SubOffscreenMain
;SubOffscreenX7:
;LDA #$0E

SubOffscreenMain:

STA $03

JSR SubIsOffscreen
BEQ Return2

LDA $5B
LSR
BCS VerticalLevel
LDA $D8,x
CLC
ADC #$50
LDA $14D4,x
ADC #$00
CMP #$02
BPL EraseSprite
LDA $167A,x
AND #$04
BNE Return2
LDA $13
AND #$01
ORA $03
STA $01
TAY
LDA $1A
CLC
ADC Table4,y
ROL $00
CMP $E4,x
PHP
LDA $1B
LSR $00
ADC Table5,y
PLP
SBC $14E0,x
STA $00
LSR $01
BCC Label20
EOR #$80
STA $00
Label20:
LDA $00
BPL Return2

EraseSprite:
LDA $14C8,x
CMP #$08
BCC KillSprite
LDY $161A,x
CPY #$FF
BEQ KillSprite
LDA #$00
STA $1938,y
KillSprite:
STZ $14C8,x
Return2:
RTS

VerticalLevel:

LDA $167A,x
AND #$04
BNE Return2
LDA $13
LSR
BCS Return2
AND #$01
STA $01
TAY
LDA $1C
CLC
ADC Table3,y
ROL $00
CMP $D8,x
PHP
LDA $1D
LSR $00
ADC Table6,y
PLP
SBC $14D4,x
STA $00
LDY $02
BEQ Label22
EOR #$80
STA $00
Label22:
LDA $00
BPL Return2
BMI EraseSprite

SubIsOffscreen:
LDA $15A0,x
ORA $186C,x
RTS



SubHorzPos:

LDY #$00
LDA $94
SEC
SBC $E4,x
STA $0F
LDA $95
SBC $14E0,x
BPL $01
INY
RTS

SetSomeYSpeed:	; ripped from $019A04

LDA $1588,x
BMI $07
LDA #$00
LDY $15B8,x
BEQ $02
LDA #$18
STA $AA,x
RTS

SetAnimationFrame:	; ripped from $018E5E

INC $1570,x
LDA $1570,x
LSR #3
AND #$01
STA $1602,x
RTS

SpriteMightWin:
LDA $77
AND #$04
CMP #$04
BEQ SpriteWins
BRA MarioWins

ImStickingTheInteractionRoutineElsewhereForReadability:
	JSL $01A7DC
	BCC NoContact95
	LDA $7D				; |
	BMI SpriteWins			;/ If he is, branch.

	LDA $72
	BEQ SpriteMightWin

	
MarioWins:
;===========================================
;Mario Hurts Sprite
;===========================================
	LDA #$01
	STA $1594,x
	
	JSL $01AA33             ;\ Set mario speed.
	JSL $01AB99             ;/ Display contact graphic.
		JSR ThrowBone
	LDA $140D		; IF spin-jumping ..
	BNE SpinKill		; Go to spin kill.
	
	LDA #$E0		;\
	STA $AA,x		; | Make sprite fall.
	LDA #$02		; |
	STA $14C8,x		;/
	LDA #$13		;\
	STA $1DF9		;/ Play sound.
	RTS

SpinKill:
	LDA #$04		;\
	STA $14C8,x		;/ Sprite status = killed by a spin-jump.
	LDA #$08		;\
	STA $1DF9		;/ Sound to play.
	JSL $07FC3B		; Show star animation effect.
	RTS
;===========================================
;Sprite Hurts Mario
;===========================================

SpriteWins:
	LDA $1490			;\ IF Mario has star power ..
	BNE HasStar			;/ Kill sprite.
	JSL $00F5B7			;\ Otherwise, hurt Mario.
NoContact95:
	RTS



;===========================================
;Killed by Star Routine
;===========================================

HasStar:
	
	LDA $167A,x		;\ Don't disable clipping when killed by a star. 
	ORA #$01		; | NOTE: We do this to not make glitched graphics show up ..
	STA $167A,x		; | when the sprite is killed by a star.
				;/  You can also check this option in the .cfg editor.

	LDA #$02		;\ Set the sprite status to ..
	STA $14C8,x		;/ Killed by a star.
	LDA #$D0		;\
	STA $AA,x		;/ Set Y speed so sprite falls down.
	INC $18D2		; Increase number of consective enemies stomped/ killed by star.
	LDA $18D2		; IF consecutive # of enemies killed by star/stomped ..
	CMP #$08		; IS 8 ..
	BCC NotEight
	LDA #$08		;\ Keep it static at 8, because you get 1-ups all the time afterwards.
	STA $18D2		;/
NotEight:
	JSL $02ACE5		; This code calls the "give points" routine.
	LDY $18D2		; Get consecutive # of enemies stomped in Y.
	CPY #$08		; If it's less than 8 once again, return.
	BCC NoSound
	LDA StarSFX,y		;\
	STA $1DF9		;/ Play sounds depending on how many enemies were stomped/killed by star.
NoSound:
	RTS			; Return.

StarSFX:         db $00,$13,$14,$15,$16,$17,$18,$19