From KeenWiki
Jump to navigation Jump to search

This page covers patches relating to the Ceilicks in Keen 6. Ceilicks are pink ceiling-dwelling enemies that spend most of their time barely visible, only coming out to attack Keen if he moves underneath them.

Sprite Type

Ceilick use sprite type 23. This is used by no other sprite and does not interact with any other sprite types.

Keen 6

#Ceilick sprite type
%patch $124C0 $17

Sprite Actions

Ceilick action structure is very simple. A Ceilick is spawned waiting and will remain so until Keen moves underneath it. When he does the Ceilick will start its attack sequence, a 21 frame long sequence that will play the same way no matter what Keen does. This sequence appears to be broken into two sub-sequences, the first part the Ceilick attacks with its tongue before vanishing; in the second part the Ceilick appears and laughs. After attacking the Ceilick returns to waiting.

The Ceilick can be shot and stunned when laughing.

$31BEW  #Ceilick waiting
$31DCW  #Ceilick attack 1
$31FAW  #Ceilick attack 2
$3218W  #Ceilick attack 3
$3236W  #Ceilick attack 4
$3254W  #Ceilick attack 5
$3272W  #Ceilick attack 6
$3290W  #Ceilick attack 7
$32AEW  #Ceilick attack 8
$32CCW  #Ceilick attack 9
$32EAW  #Ceilick attack 10
$3308W  #Ceilick attack, hide
$3326W  #Ceilick laugh  1
$3344W  #Ceilick laugh  2
$3362W  #Ceilick laugh  3
$3380W  #Ceilick laugh  4
$339EW  #Ceilick laugh  5
$33BCW  #Ceilick laugh  6
$33DAW  #Ceilick laugh  7
$33F8W  #Ceilick laugh  8
$3416W  #Ceilick laugh  9
$3434W  #Ceilick stunned

Keen 6

#When spawned
%patch $124EC [$31BEW]

#While waiting
%patch $33F0A [$0000W] #Do nothing

#When Keen is underneath
%patch $12536 [$31DCW]

#Attacking sequence
%patch $33F28 [$31FAW]
%patch $33F46 [$3218W]
%patch $33F64 [$3236W]
%patch $33F82 [$3254W]
%patch $33FA0 [$3272W]
%patch $33FBE [$3290W]
%patch $33FDC [$32AEW]
%patch $33FFA [$32CCW]
%patch $34018 [$32EAW]
%patch $34036 [$3308W]
%patch $34054 [$3326W]
%patch $34072 [$3344W]
%patch $34090 [$3362W]
%patch $340AE [$3380W]
%patch $340CC [$339EW]
%patch $340EA [$33BCW]
%patch $34108 [$33DAW]
%patch $34126 [$33F8W]
%patch $34144 [$3416W]
%patch $34162 [$31BEW]

#When shot
%patch $1258C [$3434W]

Sprite Behavior

The Ceilick has three unique behaviors, one complex and two simple. The first, complex behavior is that of waiting, detecting Keen and attacking. It is used by the first frame of the sitting Ceilick. The remaining two behaviors are exceedingly simple. The first simply plays a laughing sound and is used by the Ceilick when it reappears after attacking. The second changes a sprite's draw variable and is used by the stunned Ceilick for unknown reasons.

$11CF080ARL #Ceilick wait\attack
$11CF084CRL #Ceilick Laugh
$11CF085DRL #Ceilick stunned

Keen 6

%patch $33EFE $11CF080ARL
%patch $33F1C $00000000L

%patch $33F3A $00000000L
%patch $33F58 $00000000L
%patch $33F76 $00000000L
%patch $33F94 $00000000L
%patch $33FB2 $00000000L
%patch $33FD0 $00000000L
%patch $33FEE $00000000L
%patch $3400C $00000000L
%patch $3402A $00000000L
%patch $34048 $00000000L
%patch $34066 $11CF084CRL
%patch $34084 $00000000L
%patch $340A2 $00000000L
%patch $340C0 $00000000L
%patch $340DE $00000000L
%patch $340FC $00000000L
%patch $3411A $00000000L
%patch $34138 $00000000L
%patch $34156 $00000000L

%patch $34174 $11CF085DRL

Laughing behavior code

This is the complete code for the Ceilick laughing behavior. It is very simple, it plays a single sound once.

Keen 6

#Ceilick laugh behavior code
%patch $1253C $55 $8B $EC $B8 [$0037W]  $50 $9A $183B09F1RL     $83 $C4 $02 $5D

Stunned behavior code

This is the complete code for the Ceilick stunned behavior. It is very simple, it changes a sprite's draw variable. It is not currently known why this behavior must be used by the stunned Ceilick, but it may relate to the Ceilick's habit of vanishing.

Keen 6

#Ceilick stunned behavior code
%patch $1254D $55 $8B $EC $56 $8B $76 $06 $C7 $44 $04 [$0001W]  $5E $5D $CB

Speed and Jump Height

Neither the waiting or stunned Ceilick moves, but movement is used twice in the attacking sequence, the first time it moves down when appearing to laugh at Keen and the second time it moves up after it has finished laughing at him.

Keen 6 Animation motion

%patch $33EFA [$0000W $0000W]

%patch $33F18 [$0000W $0000W]
%patch $33F36 [$0000W $0000W]
%patch $33F54 [$0000W $0000W]
%patch $33F72 [$0000W $0000W]
%patch $33F90 [$0000W $0000W]
%patch $33FAE [$0000W $0000W]
%patch $33FCC [$0000W $0000W]
%patch $33FEA [$0000W $0000W]
%patch $34008 [$0000W $0000W]
%patch $34026 [$0000W $0000W]
%patch $34044 [$0000W $0000W] #Hide
%patch $34062 [$0000W $0010W] #Laugh
%patch $34080 [$0000W $0000W]
%patch $3409E [$0000W $0000W]
%patch $340BC [$0000W $0000W]
%patch $340DA [$0000W $0000W]
%patch $340F8 [$0000W $0000W]
%patch $34116 [$0000W $0000W]
%patch $34134 [$0000W $FFF0W]
%patch $34152 [$0000W $0000W]

%patch $34170 [$0000W $0000W]

Sprite Collision

The Ceilick has several collision values. The end result of this is that the Ceilick is only deadly when attacking and can only be shot when laughing.

Collision values

There are three values for the Ceilick's collision. When it is waiting for Keen or stunned it has no collision, meaning Keen cannot harm it, and it cannot harm Keen. It also has no collision for the first frame of its attacking sequence.

When in the licking part of its attack sequence the Ceilick uses a general 'kill Keen' collision, making it deadly, but indestructible. When hiding it has no collision again and while laughing at Keen it uses a harmless collision that allows Keen to shoot it.

Keen 6 collision values

%patch $33F02 $00000000L  #Nothing

%patch $33F20 $00000000L  #Nothing
%patch $33F3E $08F417EERL #Kill Keen
%patch $33F5C $08F417EERL #Kill Keen
%patch $33F7A $08F417EERL #Kill Keen
%patch $33F98 $08F417EERL #Kill Keen
%patch $33FB6 $08F417EERL #Kill Keen
%patch $33FD4 $08F417EERL #Kill Keen
%patch $33FF2 $08F417EERL #Kill Keen
%patch $34010 $08F417EERL #Kill Keen
%patch $3402E $08F417EERL #Kill Keen
%patch $3404C $00000000L  #Nothing (Hide)
%patch $3406A $11CF086CRL #Ceilick (Laugh)
%patch $34088 $11CF086CRL #Ceilick
%patch $340A6 $11CF086CRL #Ceilick
%patch $340C4 $11CF086CRL #Ceilick
%patch $340E2 $11CF086CRL #Ceilick
%patch $34100 $11CF086CRL #Ceilick
%patch $3411E $11CF086CRL #Ceilick
%patch $3413C $11CF086CRL #Ceilick
%patch $3415A $11CF086CRL #Ceilick

%patch $34178 $00000000L  #Nothing

Collision code

This is the complete Ceilick collision code for the unique collision the Ceilick uses when it can be stunned. On the first line there is a check for Keen's shot type. If this is detected the shot is destroyed and a number of variables changed. The Ceilick's action changes to stunned and its draw variable is set to $19.

Keen 6

#Ceilick collision
%patch $1255C $55 $8B $EC $56 $57 $8B $76 $06 $8B $7E $08 $83 $3D [$03] {$75} $30
              $8B $44 $3E $89 $44 $0C $57 $9A $0CA60EC2RL     $83 $C4 $02 $33
              $C0 $89 $44 $42 $89 $44 $40 $89 $44 $3E $8B $04 $89 $44 $44 $B8
              [$3434W]  $50 $56 $9A $08F41297RL     $83 $C4 $04 $C7 $04 [$0019W]
              $5F $5E $5D $CB


The Ceilick reuses many of its animation in its long attack sequence. Animation speed is important as it controls not only the length of each step in the sequence, but also the total sequence length. The first important value is that for the waiting Ceilick, where animation speed controls how quickly it will attack Keen (Too quick and he has no chance to escape.) The next value is that for hiding Ceilick, before it reappears to laugh at Keen. The third is how long the Ceilick hides after laughing, before it 'reset's to waiting for Keen again.

Notice that after laughing the Ceilick uses -1 for its animation, which clears its animation, meaning it has no animation at all for that frame, it is invisible and untouchable.

Keen 6 Animations

%patch $3244E [$00F6W] #Ceilick cache start
%patch $3249E [$00FDW] #Ceilick cache end

#Ceilick wait
%patch $33EEE $00F8W $00F8W #Ceilick wait for Keen
%patch $33EF8 $0014W        #Pause before licking when disturbed.

#Attack sequence
%patch $33F0C $00F8W $00F8W #Ceilick attack 1
%patch $33F16 $0006W        #Animation speed
%patch $33F2A $00F9W $00F9W #Ceilick attack 2
%patch $33F34 $0006W        #Animation speed
%patch $33F48 $00FAW $00FAW #Ceilick attack 3
%patch $33F52 $0006W        #Animation speed
%patch $33F66 $00FBW $00FBW #Ceilick attack 4
%patch $33F70 $0006W        #Animation speed
%patch $33F84 $00FCW $00FCW #Ceilick attack 5
%patch $33F8E $0006W        #Animation speed
%patch $33FA2 $00FBW $00FBW #Ceilick attack 6
%patch $33FAC $0006W        #Animation speed
%patch $33FC0 $00FAW $00FAW #Ceilick attack 7
%patch $33FCA $0006W        #Animation speed
%patch $33FDE $00FBW $00FBW #Ceilick attack 8
%patch $33FE8 $0006W        #Animation speed
%patch $33FFC $00FCW $00FCW #Ceilick attack 9
%patch $34006 $0006W        #Animation speed
%patch $3401A $00F9W $00F9W #Ceilick attack 10
%patch $34024 $000AW        #Animation speed
%patch $34038 $00F8W $00F8W #Ceilick attack 11 (Hide)
%patch $34042 $000AW        #Hiding period before laughing
%patch $34056 $00F6W $00F6W #Ceilick attack 12 (Head appears)
%patch $34060 $0010W        #Animation speed
%patch $34074 $00F7W $00F7W #Ceilick attack 13
%patch $3407E $000AW        #Animation speed
%patch $34092 $00F6W $00F6W #Ceilick attack 14
%patch $3409C $000AW        #Animation speed
%patch $340B0 $00F7W $00F7W #Ceilick attack 15
%patch $340BA $000AW        #Animation speed
%patch $340CE $00F6W $00F6W #Ceilick attack 16
%patch $340D8 $000AW        #Animation speed
%patch $340EC $00F7W $00F7W #Ceilick attack 17
%patch $340F6 $000AW        #Animation speed
%patch $3410A $00F6W $00F6W #Ceilick attack 18
%patch $34114 $000AW        #Animation speed
%patch $34128 $00F6W $00F6W #Ceilick attack 19 (Head goes up)
%patch $34132 $0010W        #Animation speed
%patch $34146 $FFFFW $FFFFW #Ceilick attack 20 (vanish)
%patch $34150 $003CW        #Hiding period

#Ceilick stunned
%patch $34164 $00FDW $00FDW #Ceilick stunned
%patch $3416E $0000W        #Animation speed


The Ceilick plays two sounds, the first is played when the Ceilick first attacks Keen while the second plays when the Ceilick's head appears to 'laugh' at Keen. Both sounds can be blocked. However it is easier to simply remove the laughing behavior (See behavior section above) since the only thing it does it play the sound.

Ceilick sounds

%patch $12528 $33     #Ceilick attack sound
%patch $12540 $37     #Ceilick laugh sound

%patch $12527 $EB $0A #Ceilick attack sound
%patch $1253F $EB $0A #Don't play Ceilick laugh sound

Clipping and foreground

The Ceilick uses 0 for its foreground variable, so it appears behind the foreground ceiling tiles it hides behind. Any other value results in amusing animation errors. It also has this value for its clipping, which means it can ignore the ceilings it hides behind.

Ceilick foreground variable

#Ceilick foreground variable
%patch $124CA [$0000W]

Ceilick clipping variable

#Ceilick clipping variable
%patch $124CF [$0000W]

Sprite-tile interaction

The Ceilick doesn't really interact with tiles in any meaningful way and so uses a basic 'draw sprite' interaction. When stunned it uses the 'stunned sprite' interaction to draw its stun stars.

Sprite tile interactions

#Ceilick wait
%patch $33F06 $08F4180ARL

#Attack sequence
%patch $33F24 $08F4180ARL
%patch $33F42 $08F4180ARL
%patch $33F60 $08F4180ARL
%patch $33F7E $08F4180ARL
%patch $33F9C $08F4180ARL
%patch $33FBA $08F4180ARL
%patch $33FD8 $08F4180ARL
%patch $33FF6 $08F4180ARL
%patch $34014 $08F4180ARL
%patch $34032 $08F4180ARL
%patch $34050 $08F4180ARL
%patch $3406E $08F4180ARL
%patch $3408C $08F4180ARL
%patch $340AA $08F4180ARL
%patch $340C8 $08F4180ARL
%patch $340E6 $08F4180ARL
%patch $34104 $08F4180ARL
%patch $34122 $08F4180ARL
%patch $34140 $08F4180ARL
%patch $3415E $08F4180ARL

#Ceilick stunned
%patch $3417C $08F419AFRL

Action type

Like all stunned sprites the stunned Ceilick action is type 2. The waiting Ceilick action is type 2 as well, as this allows it to react to Keen most quickly. All other actions are very basic and thus type 0.

Sprite action types

#Ceilick wait
%patch $33EF2 [$0002W]

#Attack sequence
%patch $33F10 [$0000W]
%patch $33F2E [$0000W]
%patch $33F4C [$0000W]
%patch $33F6A [$0000W]
%patch $33F88 [$0000W]
%patch $33FA6 [$0000W]
%patch $33FC4 [$0000W]
%patch $33FE2 [$0000W]
%patch $34000 [$0000W]
%patch $3401E [$0000W]
%patch $3403C [$0000W]
%patch $3405A [$0001W]
%patch $34078 [$0000W]
%patch $34096 [$0000W]
%patch $340B4 [$0000W]
%patch $340D2 [$0000W]
%patch $340F0 [$0000W]
%patch $3410E [$0000W]
%patch $3412C [$0001W]
%patch $3414A [$0000W]

#Ceilick stunned
%patch $34168 [$0002W]

Deprotect and stick to ground

The Ceilick has little need for either of these variables and so has a value of 0 for both in all of its actions. The exception is any action where the Ceilick's head is visible, which deprotects its animation for some reason.

Sprite deprotect, stick

#Ceilick wait
%patch $33EF4 [$0000W $0000W]

#Attack sequence
%patch $33F12 [$0000W $0000W]
%patch $33F30 [$0000W $0000W]
%patch $33F4E [$0000W $0000W]
%patch $33F6C [$0000W $0000W]
%patch $33F8A [$0000W $0000W]
%patch $33FA8 [$0000W $0000W]
%patch $33FC6 [$0000W $0000W]
%patch $33FE4 [$0000W $0000W]
%patch $34002 [$0000W $0000W]
%patch $34020 [$0000W $0000W]
%patch $3403E [$0000W $0000W]
%patch $3405C [$0001W $0000W]
%patch $3407A [$0001W $0000W]
%patch $34098 [$0001W $0000W]
%patch $340B6 [$0001W $0000W]
%patch $340D4 [$0001W $0000W]
%patch $340F2 [$0001W $0000W]
%patch $34110 [$0001W $0000W]
%patch $3412E [$0001W $0000W]
%patch $3414C [$0001W $0000W]

#Ceilick stunned
%patch $3416A [$0001W $0000W]

Sprite spawn code

In the initiation code notice the Ceilick cache being set ($C7 $06 $CD3BW $0001W.) Also notice the three difficulties of Ceilick that are possible.

In the spawning code the last blue highlighted value is the sprite action the sprite uses as it proceeds to act in-level. $C7 $02 $xxxxW sets the sprite activity, $C7 $07 $xxxxW sets the sprite type, $C7 $20 $xxxxW sets the foreground value.

The Ceilick always starts the level moving down though it has no need to. $C7 $47 $10 $xxxxW is the vertical direction the sprite starts moving in, either $0001W (Facing down), $FFFFW (Facing up) or $0000W (Neither, never used.) $C7 $47 $0E $xxxxW is the horizontal direction.

Keen 6

#Location of initiation code
%patch $E9F4 $03EEW #Easy Ceilick (At $E80E)
%patch $E9F6 $03E4W #Medium Ceilick (At $E804)
%patch $E9F8 $03DAW #Hard Ceilick (At $E7FA)

#Ceilick initiation code
%patch $E7FA $83 $3E {$75A8W}  [$03] {$7D} $03 $E9 $00C3W  $83 $3E {$75A8W}  [$02] {$7D}
             $03 $E9 $00B9W  $57 $56 $9A {$11CF07BCRL}     $83 $C4 $04 $C7 $06
             $CD3BW  $0001W  $E9 $00A6W

#Ceilick spawning code
%patch $124AC $55 $8B $EC $33 $C0 $50 $9A $069A1E25RL     $83 $C4 $02 $8B $1E
              $66 $A9 $C7 $07 [$0017W]  $C7 $47 $02 [$0001W]  $C7 $47 $20 [$0000W]
              $C7 $47 $06 [$0000W]  $8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B
              $46 $08 $D3 $E0 $89 $47 $3E $89 $47 $0C $C7 $47 $10 [$0001W]  $B8
              [$31BEW]  $50 $53 $9A $08F41219RL     $83 $C4 $04 $5D $CB