Patch:Sour Grape

From KeenWiki
Jump to navigation Jump to search

Sour Grapes are purple, rotund creatures that are found hanging from ceilings in many levels in Tuberia in Keen Dreams, notably Grape Grove. They wait for Keen to pass below them, then attempt to fall on top of him. They bounce when they hit the ground and after stopping will then rise back to their original positions.


Sprite Type

Grape use type 10 which has no impact on any other sprites save for affecting how Keen reacts to it.

Keen Dreams

#Grape sprite type
%patch $8537 [$0A]


Sprite Actions

The Grape has a limited set of actions. It is spawned in its 'waiting' action which is the action that checks to see if it can fall on Keen. While in this action it does nothing until Keen is below it in which case it goes to the falling action.

There is a special check in Keen's sprite collision that makes the falling Grape's action (and only that action) deadly to him. While falling the Grape doesn't change until it hits a floor at which point it becomes a rising Grape.

The rising Grape changes to the stopping Grape. The stopping Grape becomes a waiting Grape when it touches a ceiling.

Actions:
$1C90W #Grape wait
$1CAEW #Grape fall
$1CCCW #Grape rise
$1CEAW #Grape stop

Keen Dreams

#Spawn Grape
%patch $855C [$1C90W]

#Waiting Grape sequence
%patch $2571C [$0000W]

#Grape fall when Keen is near
%patch $85E4 [$1CAEW]

#Falling Grape is deadly check
%patch $78E4 [$1CAEW]

#Grape fall (Wait to land)
%patch $2573A [$0000W]

#Falling Grape hits a floor
%patch $865D [$1CCCW]

#Grape rise
%patch $25758 [$1CEAW]

#Grape stop
%patch $25776 [$0000W]

#Stopping Grape hits a ceiling
%patch $8605 [$1C90W]


Grapes don't rise

This patch prevents Sour Grapes don't rise, they simply sit on the ground forever.

Keen Dreams

#Fallen grape doesn't rise
%patch $8639 $EB


Sprite Behavior

The Grape does not have any behaviors of its own; its unknown action uses an unknown behavior while it uses a general 'move through the air' behavior when falling. While rising and sitting it has no behavior at all.

Keen Dreams

#Grape wait
%patch $25710 $07C50917RL

#Grape fall
%patch $2572E $07C501A4RL

#Grape rise
%patch $2574C $00000000L

#Grape stop
%patch $2576A $00000000L


Sitting Grape behavior code

This is the complete code for the Sour Grape's waiting behavior. This causes it to fall on Keen when he passes underneath it.

The first few lines check the Grape's hitbox variables against Keen's hitbox variables. On line 2 there are two complimentary checks, the first detects whether the left side of Keen's hitbox is right of the right side of the Grape's, the second checks whether the right side of Keen's hitbox is left of the left side of the Grape's. Combined these two checks result in a 'pass' if Keen is horizontally touching the Grape's hitbox. On line 3 there is a third check of whether Keen's vertical position is greater than that of the Grape's (That is he is lower than the Grape in the level.) Combined with the first two checks this causes the rest of the code to only run if Keen is underneath the Grape.

There is a final check on line 7 for whether or not a floor is between the Grape and Keen (There is no point falling if this is the case.) if there is not then the Grape will change its action to that of a falling Grape and play the falling sound.

Keen Dreams

#Sitting Grape behavior code
%patch $8567 $55 $8B $EC $83 $EC $08 $56 $57 $8B $76 $06 $8B $1E $34 $70 $8B
             $47 [$22] $3B $44 [$26] {$77} $73 $8B $47 [$26] $3B $44 [$22] {$72} $6B $8B
             $47 [$0C] $3B $44 [$0C] {$72} $63 $8B $44 $32 $89 $46 $FE $8B $1E $34
             $70 $8B $47 $2E $89 $46 $FC $8B $5E $FE $D1 $E3 $8B $87 $9C $BC
             $D1 $E8 $D1 $E0 $8B $16 $46 $8F $8B $5C $34 $D1 $E3 $03 $C3 $89
             $56 $FA $89 $46 $F8 $8B $7E $FE $EB $1B $C4 $5E $F8 $26 $8B $1F
             $8E $06 $3C $8F $26 $80 $BF $36 $0D [$00] {$75} $1E $47 $A1 $86 $DE
             $D1 $E0 $01 $46 $F8 $3B $7E $FC $72 $E0 $C7 $44 $1E [$1CAEW]  $B8
             [$0018W]  $50 $9A $10BB1282RL     $44 $44 $5F $5E $8B $E5 $5D $CB


Sitting Grape behavior code without sound

This patch is identical to that above, except it omits the awakening sound. This helps illustrate how the jumps work and is slightly more compact.

Keen Dreams

#Sitting Grape behavior code without sound
%patch $8567 $55 $8B $EC $83 $EC $08 $56 $57 $8B $76 $06 $8B $1E $34 $70 $8B
             $47 [$22] $3B $44 [$26] {$77} $68 $8B $47 [$26] $3B $44 [$22] {$72} $60 $8B
             $47 [$0C] $3B $44 [$0C] {$72} $58 $8B $44 $32 $89 $46 $FE $8B $1E $34
             $70 $8B $47 $2E $89 $46 $FC $8B $5E $FE $D1 $E3 $8B $87 $9C $BC
             $D1 $E8 $D1 $E0 $8B $16 $46 $8F $8B $5C $34 $D1 $E3 $03 $C3 $89
             $56 $FA $89 $46 $F8 $8B $7E $FE $EB $1B $C4 $5E $F8 $26 $8B $1F
             $8E $06 $3C $8F $26 $80 $BF $36 $0D [$00] {$75} $13 $47 $A1 $86 $DE
             $D1 $E0 $01 $46 $F8 $3B $7E $FC $72 $E0 $C7 $44 $1E [$1CAEW]  $5F
             $5E $8B $E5 $5D $CB


Speed and Jump Height

The Grape has no real animation speeds with one exception. The Grape's stopping action has a slight upwards speed to 'press' it against the ceiling, ready to fall again.

Sprite speeds

#Grape wait
%patch $2570C [$0000W $0000W]

#Grape fall
%patch $2572A [$0000W $0000W]

#Grape rise
%patch $25748 [$0000W $0000W]

#Grape stop
%patch $25766 [$0000W $FFF0W]


Sprite collision

Like nearly all sprites in Keen Dreams the Grape does not have a sprite collision. Instead Keen and his shots react to them and their sprite types.

Keen Dreams

#Grape wait
%patch $25714 $00000000L

#Grape fall
%patch $25732 $00000000L

#Grape rise
%patch $25750 $00000000L

#Grape stop
%patch $2576E $00000000L


Animations

Grapes have only two animations for all of their actions.

Keen Dreams

#Cache
%patch $23E80 $0117W #Grape cache start
%patch $23EAC $0118W #Grape cache end

#Grape wait
%patch $25700 $0117W $0117W
%patch $2570A $0000W        #Animation speed

#Grape fall
%patch $2571E $0118W $0118W
%patch $25728 $0000W        #Animation speed

#Grape rise
%patch $2573C $0117W $0117W
%patch $25746 $001EW        #Animation speed

#Grape stop
%patch $2575A $0117W $0117W
%patch $25764 $0000W        #Animation speed


Sounds

The Grape makes two sounds, one when falling and another when bouncing on the ground. both can be blocked.

Keen Dreams

#Sounds
%patch $85E7 $18     #Sour Grape fall sound
%patch $863C $11     #Sour Grape bounce sound

#Don't make sounds
%patch $85E6 $EB $09 #Don't play Sour Grape fall sound
%patch $863B $EB $09 #Don't play Sour Grape bounce sound


Sprite-tile interaction

The Grape uses a generic 'nothing' tile interaction when waiting and rising. It has a unique interaction when falling that lets it bounce and another when sitting that allows it to settle up against ceilings.

Keen Dreams

#Grape sit
%patch $25718 $07C501DDRL

#Grape fall
%patch $25736 $07C509DERL

#Grape rise
%patch $25754 $07C501DDRL

#Grape stop
%patch $25772 $07C509A7RL


Falling Grape tile interaction code

This is the tile interaction code used by the falling Grape. On the first line a check is made to see if the Grape is touching a floor. If it is it plays sound 11 and reverses and decreases its vertical speed (Bounces) If its vertical speed is zero then it goes to the rising Grape action on line 3. The remainder of the code draws the sprite.

Keen Dreams

#Falling Grape tile interaction code
%patch $862E $55 $8B $EC $56 $8B $76 $06 $83 $7C {$36} [$00] {$74} $2D $B8 [$0011W]
             $50 $9A $10BB1282RL     $44 $44 $8B $44 $18 $D1 $E0 $F7 $D8 $BB
             [$0003W]  $99 $F7 $FB $89 $44 $18 $83 $7C $18 $E0 $7E $0C $B8 [$1CCCW]
                 $50 $56 $0E $E8 $F840W  $83 $C4 $04 $33 $C0 $50 $50 $FF $74
             $20 $FF $74 $0C $FF $74 $0A $8B $C6 $05 $46 $00 $50 $9A $0E450DC5RL
                     $83 $C4 $0C $5E $5D $CB


Stopping Grape tile interaction code

This is the tile interaction code used by the stopping Grape. On the first line a check is made to see if the Grape is touching a ceiling. If it is it goes to the waiting Grape action. The remainder of the code draws the sprite.

Keen Dreams

#Sitting Grape tile interaction code
%patch $85F7 $55 $8B $EC $56 $8B $76 $06 $83 $7C {$3A} [$00] {$74} $0C $B8 [$1C90W]
             $50 $56 $0E $E8 $F898W  $83 $C4 $04 $33 $C0 $50 $50 $FF $74 $20
             $FF $74 $0C $FF $74 $0A $8B $C6 $05 $46 $00 $50 $9A $0E450DC5RL
                 $83 $C4 $0C $5E $5D $CB


Action type

Sitting Grapes need to react quickly, so use a type 2 action. The same is true of falling graps. Rising Grapes are more simple and thus type 0. Stopping Grapes are type 1 as they have some animation motion that must occur smoothly.

Sprite action types

#Grape sit
%patch $25704 [$0002W]

#Grape fall
%patch $25722 [$0002W]

#Grape rise
%patch $25740 [$0000W]

#Grape stop
%patch $2575E [$0001W]


Deprotect and stick to ground

The Grape has no need for either of these variables and so has a value of 0 for both in all of its actions.

Sprite deprotect, stick

#Grape sit
%patch $25706 [$0000W $0000W]

#Grape fall
%patch $25724 [$0000W $0000W]

#Grape rise
%patch $25742 [$0000W $0000W]

#Grape stop
%patch $25760 [$0000W $0000W]


Sprite spawn code

There is one type of Sour Grape. In its initiation code its cache is set in $C7 $06 $70C4W $0001W.

The last blue highlighted value is the sprite action the sprite uses as it proceeds to act in-level. $C7 $07 $xxxxW sets the sprite type, $C7 $47 $06 $xxxxW sets the |clipping, and $C7 $47 $0E $xxxxW is the horizontal direction the sprite starts moving in, either $0001W (Facing right), $FFFFW (Facing left) or $0000W (Neither, seldom used.) $C7 $47 $10 $xxxxW is the vertical direction and works similarly. Keen always starts moving downwards. The Grape spawns facing down and right.

Keen Dreams

#Sour Grape initiation pointer
%patch $4A37 $03BAW #Sour Grape (At $488A)

#Sour Grape initiation code
%patch $488A $FF $36 $7052W  $FF $36 $7050W  $9A $07C508D4RL     $83 $C4 $04
             $8B $1E $3E $70 $C7 $47 $02 $0000W  $C7 $06 $70C4W  $0001W  $E9
             $0120W

#Sour Grape spawn code
%patch $8524 $55 $8B $EC $33 $C0 $50 $9A $044D01C9RL     $44 $44 $8B $1E $3E
             $70 $C7 $07 [$000AW]  $8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B
             $46 $08 $D3 $E0 $89 $47 $0C $C7 $47 $0E [$0001W]  $C7 $47 $10 [$0001W]
                 $B8 [$1C90W]  $50 $FF $36 $3E $70 $9A $044D1212RL     $83 $C4
             $04 $5D $CB