Patch:Dart Gun
The Dart Gun in Keen 4 is an invisible sprite that regularly spawns new sprites, or darts. There are four different varieties of gun (Though they are not different sprites in themselves.) that shoot in different directions. Similar sprites occur in Keen 3 and Keen 6, as well as in Keen 5 and the watermelons in Keen Dreams. this page also covers patches relating to the dart sprites produced.
Sprite Type
Dart guns are type 1, specifically to avoid interactions with any other sprites. Darts are type 31, but this doesn't affect any sprites by default.
Keen 4
#Sprite type
%patch $12873 $01 #Dart gun
%patch $1292B $1F #Darts
Sprite Actions
There are four separate sets of actions relating to darts. The first is the dart gun. It is spawned behaving as a Dart gun (as expected); a single frame loop running the 'make dart' code every time it loops. The remaining three are darts, horizontal (left and right), up and down. Each is spawned in the first frame of its two frame loop which it uses until offscreen or destroyed. Note that the left and right Darts use the same actions.
Actions: $3962W #Dart gun $3980W #Dart horizontal 1 $399EW #Dart horizontal 2 $39BCW #Dart up 1 $39DAW #Dart up 2 $39F8W #Dart down 1 $3A16W #Dart down 2
Keen 4
#Spawn Dart gun
%patch $128EC {$3962W}
#Dart gun loop
%patch $327EE {$3962W}
#Spawn Darts
%patch $1296D {$3980W} #Spawn Dart left
%patch $129A7 {$3980W} #Spawn Dart right
%patch $12950 {$39BCW} #Spawn Dart up
%patch $1298A {$39F8W} #Spawn Dart down
#Dart horizontal loop
%patch $3280C {$399EW} #Dart horizontal 1
%patch $3282A {$3980W} #Dart horizontal 2
#Dart up loop
%patch $32848 {$39DAW} #Dart up 1
%patch $32866 {$39BCW} #Dart up 2
#Dart down loop
%patch $32884 {$3A16W} #Dart down 1
%patch $328A2 {$39F8W} #Dart down 2
Sprite Behavior
The only sprite with a behavior is the dart gun, and this behavior regularly produces one of the three dart sprites, setting their direction and other properties. Darts themselves do nothing.
Behaviors: $11A20EE6RL #Dart gun
Keen 4
#Dart gun
%patch $327E2 {$11A20EE6RL} #Dart gun
#Horizontal darts
%patch $32800 {$00000000L} #Nothing
%patch $3281E {$00000000L} #Nothing
#Up darts
%patch $3283C {$00000000L} #Nothing
%patch $3285A {$00000000L} #Nothing
#Down darts
%patch $32878 {$00000000L} #Nothing
%patch $32896 {$00000000L} #Nothing
Darts look and act like enemy shots
This patch alters the Darts so that they behave like the Enemy Shooters in Keen 5 and 6. That is they produce shots that look the same when moving in any direction and that smash on tiles with a sound. Note that this patch is incompatible with some of the patches on this page. Those will need to be incorporated into this patch.
The first section makes the Down darts spawn properly. The second section makes the Darts have 4 animation frames when moving. The third section sets up the correct animations; 384-387. None of these sections should be tinkered with. The fourth section contains the Dart's horizontal and Vertical speeds which can be changed as desired. (The Dart directions are elsewhere on this page.)
The fifth section makes the Darts use a custom smashing code when they hit walls of any kind. The sixth section is this code. The first blue value is what the Dart becomes when it smashes; the second blue value is the sound made when the Dart smashes. (In this patch it is the same as that used when Keen's shot smashes, but this can be changed.)
The final section is the smashed Dart actions. These contain things like the Smashed Darts animations, animation speed and tile interaction. (The first two are highlighted in blue as they are most important.) These overwrite the down Dart's action so placing down Dart patches after this patch will change things.
Darts look and act like enemy shots
#Down Darts start with horizontal action
%patch $1298A $3980W
#All Darts have 4 frames
%patch $3282A $39BCW
%patch $32866 $3980W
#Animations are correct
%patch $3282C $0180W $0182W
%patch $3284A $0181W $0183W
#Both horizontal and vertical Darts can move in both directions
%patch $327FC [$0040W $0040W]
%patch $3281A [$0040W $0040W]
%patch $32838 [$0040W $0040W]
%patch $32856 [$0040W $0040W]
#Darts smash like Keen's shots
%patch $126E2 $2EE7011FRL
#Dart smash code = $2EE7011FRL
%patch $2EF8F $55 $8B $EC $56 $8B $76 $06 $C7 $04 $0001W $B8 [$39F8W] $50 $56
$9A $09DC120ARL $83 $C4 $04 $B8 [$0019W] $50 $9A $187409F1RL
$83 $C4 $02 $5E $5D $CB
#Smashed Dart sequence: start = $39F8W
%patch $32868 [$017FW $017FW] $0000W $0000W $0000W [$000CW] $0000W $0000W
$00000000L $00000000L $09DC176ERL $3A16W
%patch $32886 [$017EW $017EW] $0000W $0000W $0000W [$000CW] $0000W $0000W
$00000000L $00000000L $09DC176ERL $0000W
Darts obey gravity
This patch makes the Darts obey gravity; that is they will 'curve' downwards and eventually fall vertically like the Berkelod's shots. This is done by changing their behavior, action type and how they obtain their horizontal speed. The two blue values are how fast the Dart start moving horizontally when produced.
This patch is incompatible with the Dart directions patches since it overwrites part of that patch to give the darts speed.
Darts obey gravity
#Make Darts fall
%patch $32800 $09DC16E5RL
%patch $3281E $09DC16E5RL
%patch $327F4 $0003W
%patch $32812 $0003W
#Change how horizontal Darts get speed
%patch $12969 $16 [$0040W] #Right Dart
%patch $129A3 $16 [$FFC0W] #Left dart
Speed and Jump Height
The Dart Gun doesn't move, as is expected. Darts move either horizontally or vertically by default, the direction of their movement being determined by the dart's direction below. Due to having different sprites, up and down darts have different speeds.
Keen 4
#Shooter
%patch $327DE [$0000W $0000W]
#Horizontal darts
%patch $327FC [$0040W $0000W]
%patch $3281A [$0040W $0000W]
#Up darts
%patch $32838 [$0000W $0040W]
%patch $32856 [$0000W $0040W]
#Down darts
%patch $32874 [$0000W $0040W]
%patch $32892 [$0000W $0040W]
Dart direction
The darts have their directions set on creation. That is, in what direction they'll move. Each dart can move both horizontally and vertically, or both at the same time. This is controlled by two variables, the horizontal and vertical direction, and whether they're right\down (1), left\up (-1) or still (0)
Keen 4 dart directions
#Down dart
%patch $12948 $0000W #Horizontal direction
%patch $1294D $FFFFW #Vertical direction
#Right Dart
%patch $12965 $0001W #Horizontal direction
%patch $1296A $0000W #Vertical direction
#Up Dart
%patch $12982 $0000W #Horizontal direction
%patch $12987 $0001W #Vertical direction
#Left dart
%patch $1299F $FFFFW #Horizontal direction
%patch $129A4 $0000W #Vertical direction
Sprite Collision
The dart collisions are quite simple. The dart gun has no collision, it does not interact with other sprites. (Thus it cannot be destroyed, or hurt Keen.) The darts themselves use the 'misc lethal' collision, killing Keen if they touch him.
Keen 4 collision values
#Dart shooter
%patch $327E6 {$00000000L} #Nothing
#Horizontal darts
%patch $32804 {$09DC1752RL} #Deadly to Keen
%patch $32822 {$09DC1752RL} #Deadly to Keen
#Up darts
%patch $32840 {$09DC1752RL} #Deadly to Keen
%patch $3285E {$09DC1752RL} #Deadly to Keen
#Down darts
%patch $3287C {$09DC1752RL} #Deadly to Keen
%patch $3289A {$09DC1752RL} #Deadly to Keen
Animations
The dart animations are simple, darts have two animations and the dart gun is invisible. Note that the dart gun animation speed is also the frequency it produces darts.
The 'when spawned' sprites are used to position darts and should be the same as the first frame of the dart produced, otherwise your darts will be off-center. (See position list section.)
Keen 4
#Cache
%patch $3070E $017CW #Darts Cache start
%patch $30758 $0183W #Darts cache end
#Dart shooter
%patch $327D2 [$0000W $0000W] #(No sprites)
%patch $327DC [$0096W] #Animation speed
#Spawn sprites
%patch $128B2 [$017CW] #Up dart
%patch $128C6 [$0180W] #Right dart
%patch $128D6 [$017EW] #Down dart
%patch $128E9 [$0182W] #Left dart
#Horizontal darts
%patch $327F0 $0182W $0180W
%patch $327FA $0006W #Animation speed
%patch $3280E $0183W $0181W
%patch $32818 $0006W #Animation speed
#Dart up
%patch $3282C $017CW $017CW
%patch $32836 $0006W #Animation speed
%patch $3284A $017DW $017DW
%patch $32854 $0006W #Animation speed
#Dart down
%patch $32868 $017EW $017EW
%patch $32872 $0006W #Animation speed
%patch $32886 $017FW $017FW
%patch $32890 $0006W #Animation speed
Sounds
The dart shooters make a sound each time they produce a dart. This sound can be blocked.
Keen 4
#Dart gun shoot sound
%patch $129B4 [$29]
#Don't make sound:
%patch $129B3 $EB $0A
Each different direction Dart has a unique sound
This patch makes it so that the left, up, right and down Darts each have a different sound when they are produced. This is done by making the first action of three (not four) of the Darts a 1-tic special action that does nothing but play a sound. This can be a bit tricky since the special actions should use the same animations as the first action of the Dart they change to.
The left Dart is unchanged, its sound is the same as the sound the Dart Shooter uses. The sounds used by the other Darts must have an equal or higher priority than the Dart Shooter's sound (In a sense they must be equal or more 'important') otherwise the Dart Shooter's sound will play over them. If a modder is editing the sounds also then they will be able to easily edit the priorities, if they are not then they will have to carefully choose the sounds they use. The sounds used in this patch are random and not meant to act as a guide. The sounds are the final 4 blue values.
As noted above the animations of the new Dart actions should be the same as the first frame of the Dart they transform into. This prevents spawning problems. They should also have the same tile collision and sprite collision if these are changed. The actions have no speed and the smallest possible animation delay.
This patch uses the EGAGRAPH check skip and thus is incompatible with other patches that use it without tweaking.
Unique Dart sound patch: Add 3 new sounds to Darts
#Spawn Darts: 3 new actions to play 3 new sounds
%patch $129A7 $E8D0W #Spawn Dart right
%patch $12950 $E8EEW #Spawn Dart up
%patch $1298A $E90CW #Spawn Dart down
#New Dart actions, play unique sounds, goto 1st Dart actions
%patch $3D740 $0182W $0180W $0000W $0000W $0000W $0001W $0000W $0000W #Right = $E8D0W
$037D0526RL $09DC1752RL $11A20CA1RL $3980W
%patch $3D75E $017CW $017CW $0000W $0000W $0000W $0001W $0000W $0000W #Up = $E8EEW
$037D0535RL $09DC1752RL $11A20CA1RL $39BCW
%patch $3D77C $017EW $017EW $0000W $0000W $0000W $0001W $0000W $0000W #Down = $E90CW
$037D0544RL $09DC1752RL $11A20CA1RL $39F8W
#Play sound behaviors 1-3 (Behaviors share code)
%patch $3CE5 $90 $90 #Free up space
%patch $3CF6 $55 $8B $EC $56 $8B $76 $06 $8B $44 $0A $B8 [$000AW] $EB $1C #Right =$037D0526RL
$55 $8B $EC $56 $8B $76 $06 $8B $44 $0A $B8 [$0022W] $EB $0D #Up =$037D0535RL
$55 $8B $EC $56 $8B $76 $06 $8B $44 $0A $B8 [$000DW] $50 $9A #Down =$037D0544RL
$187409F1RL $83 $C4 $02 $5E $5D $CB
#Dart gun shoot sound
%patch $129B4 [$29]
Sprite positioning
The positioning of darts is used to ensure that the same sprite (The Dart shooter) can produce Darts using different animation and moving in different directions without these Darts looking odd. This is controlled by the position list (Below.) Darts may have one or two positions set and two of the positions are negative.
Keen 4
#Where darts are spawned relative to shooter
%patch $128A9 [$30] #Up dart horizontal position in pixels (Negative)
%patch $128AD [$0090W] #Up dart vertical position in pixels
%patch $128BD [$0080W] #Right dart horizontal position in pixels
%patch $128C2 [$50] #Right dart vertical position in pixels
%patch $128D1 [$0090W] #Down dart horizontal position in pixels
%patch $128E1 [$70] #Left dart horizontal position in pixels
%patch $128E5 [$30] #Left dart vertical position in pixels (Negative)
Position list and code
There is a pointer list that controls what code is executed for each of the four Dart directions. In essence this positions them and gives them their starting animation. (Oddly it does not set their direction.)
Keen 4 Dart position list
#List length
%patch $12898 $03
#List location
%patch $128A0 $0EDEW #$128FE
#Dart position list
%patch $128FE $0E82W #Up (At $128A2)
%patch $12900 $0E96W #Right (At $128B6)
%patch $12902 $0EAAW #Down (At $128CA)
%patch $12904 $0EBAW #Left (At $128DA)
There are four position codes as expected. The position codes set the horizontal ($0A) and vertical ($0C) offsets and the starting sprite ($1E $xxxxW). $6F before a value makes it negative while $47 keeps it positive. $81 means to use a two byte value and $83 a one byte value. Here the positive\negative and variable bytes are colored brown and the values colored blue. See also Patch:Galaxy Sprite Parameters.
Thus $83 $6F $0C $30 $81 $47 $0A $0090W in the upwards positioning code should be read as follows: 'Use one byte. Make it negative. Make it the vertical position. make it 30. Then use two bytes. Keep them positive. Make them the horizontal position. Make them $0090. Two byte values are needed for anything larger than $80 (negative or positive.)
Using this it is a simple matter to work out what all the positioning codes do. There is also a 'finisher' code that all Darts use after their positioning codes. It is included here for completeness. It sets the Dart's action and produces it.
Keen 4 Dart position codes
#Upwards Dart positioning code
%patch $128A2 $8B $1E $D8 $A7 $83 {$6F $0C} [$30] $81 {$47 $0A} [$0090W] $C7 {$47 $1E}
[$017CW] $EB $35
#Rightwards Dart positioning code
%patch $128B6 $8B $1E $D8 $A7 $81 {$47 $0A} [$0080W] $83 {$47 $0C} [$50] $C7 {$47 $1E}
[$0180W] $EB $21
#Downwards Dart positioning code
%patch $128CA $8B $1E $D8 $A7 $81 {$47 $0A} [$0090W] $C7 {$47 $1E} [$017EW] $EB $11
#Leftwards Dart positioning code
%patch $128DA $8B $1E $D8 $A7 $83 {$47 $0C} [$70] $83 {$6F $0A} [$30] $C7 {$47 $1E} [$0182W]
#Finisher code
%patch $128DA $B8 [$3962W] $50 $FF $36 $D8 $A7 $9A $09DC118CRL
$83 $C4 $04 $5E $5D $CB
Clipping and foreground
The Dart Gun is given clipping of 0, that is, pass through tiles; possibly so it can shoot darts from walls. Darts do not appear to have clipping set.
Keen 4
#Dart gun clipping
%patch $12887 $0000W
Sprite-tile interaction
Dart shooters do not interact with tiles, as expected. Darts use the 'enemy shot' interaction; they vanish when they hit a tile that blocks in any direction.
Keen 4
#Dart gun
%patch $327EA $00000000L
#Horizontal darts
%patch $32808 $11A20CA1RL
%patch $32826 $11A20CA1RL
#Up darts
%patch $32844 $11A20CA1RL
%patch $32862 $11A20CA1RL
#Down darts
%patch $32880 $11A20CA1RL
%patch $3289E $11A20CA1RL
Default tile interaction code
This is the complete tile interaction code for the default Darts. The first part consists of four checks; these check if the left, top, right and bottom sides of any tile the Dart is touching are solid. If anyside is then the Dart will run the 'vanish' code $9A $06BD1E8BRL. Otherwise it proceeds on to the second part of the tile interaction which simply ensures the Dart remains visible.
Keen 4
#Complete Dart tile itneraction code
%patch $126C1 $55 $8B $EC $56 $8B $76 $06 $83 $7C {$36} [$00] {$75} $12 $83 $7C {$38}
[$00] {$75} $0C $83 $7C {$3A} [$00] {$75} $06 $83 $7C {$3C} [$00] {$74} $0C $56
$9A $06BD1E8BRL $83 $C4 $02 $5E $5D $CB $FF $74 $20 $33 $C0
$50 $FF $74 $1E $FF $74 $0C $FF $74 $0A $8B $C6 $05 $46 $00 $50
$9A $16541641RL $83 $C4 $0C $5E $5D $CB
Darts don't vanish when they hit tiles
This patch stops the darts vanishing when they hit solid tiles. They will however stop moving.) If nothing else is done they will rapidly build up and crash the game so some other manner of removing them must be used. (Darts destroy each other, vanish after a fixed time, exit the level... simply going offscreen will not work.)
This works by setting the Dart's tile collision to 'sit' so they don't interact with any other tiles.
Keen 4
#Darts don't vanish when they hit tiles
%patch $32808 $09DC176ERL #Horizontal darts
%patch $32826 $09DC176ERL
%patch $32844 $09DC176ERL #Up darts
%patch $32862 $09DC176ERL
%patch $32880 $09DC176ERL #Down darts
%patch $3289E $09DC176ERL
Darts smash like Keen's shots
This patch causes darts to smash into tiles just like Keen's shots, making the same noise and smashed shot sprite instead of just vanishing. This requires the creation of a new tile collision code.
Darts smash like Keen's shots
#Use new tile collision
%patch $32808 $2EE70180RL #Horizontal darts
%patch $32826 $2EE70180RL
%patch $32844 $2EE70180RL #Up darts
%patch $32862 $2EE70180RL
%patch $32880 $2EE70180RL #Down darts
%patch $3289E $2EE70180RL
#Hit tiles and dartsmash tile collision = $2EE70180RL
%patch $2EFF0 $55 $8B $EC $56 $8B $76 $06 $83 $7C $36 $00 $75 $12 $83 $7C $38
$00 $75 $0C $83 $7C $3A $00 $75 $06 $83 $7C $3C $00 $74 $0C $56
$9A $0D8F0D43RL $83 $C4 $02 $5E $5D $CB $FF $74 $20 $33 $C0
$50 $FF $74 $1E $FF $74 $0C $FF $74 $0A $8B $C6 $05 $46 $00 $50
$9A $16541641RL $83 $C4 $0C $5E $5D $CB
Action type
Dart guns are type 0, they sit and do nothing. Darts are type 1, they move smoothly through the air.
Keen 4
#Dart gun
%patch $327D6 [$0000W]
#Horizontal dart
%patch $327F4 [$0001W]
%patch $32812 [$0001W]
#Up dart
%patch $32830 [$0001W]
%patch $3284E [$0001W]
#Down dart
%patch $3286C [$0001W]
%patch $3288A [$0001W]
Deprotect and stick to ground
Darts and dart guns do not use either of these values since they have no interaction with sloped tiles at all.
Keen 4
#Dart gun
%patch $327D8 [$0000W $0000W]
#Horizontal darts
%patch $327F6 [$0000W $0000W]
%patch $32814 [$0000W $0000W]
#Up darts
%patch $32832 [$0000W $0000W]
%patch $32850 [$0000W $0000W]
#Down darts
%patch $3286E [$0000W $0000W]
%patch $3288C [$0000W $0000W]
Sprite spawn code
There are four kinds of Dart shooter which are divided further into three different difficulties in the game. Notice that there are three initiation codes, one for each difficulty, instead of four; one for each type. In each initiation code notice the Dart cache being set ($C7 $06 $CB79W $0001W.) Finally notice that all three initiation codes go to the same spawning codes; that is where the different types of Dart shooter are differentiated.
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 last part of the Dart shooter's spawn code contains the Dart positioning code covered in a previous section. This makes it quite complex. $0EDEW is where the position list is located, this has 3 1 entries. The position code is marked as explained above and that previous section should be consulted for information on how it works.
Location of initiation code
%patch $EEED [$0489W] #Easy Up Dart (At $ED79)
%patch $EEEF [$0489W] #Easy Right Dart (At $ED79)
%patch $EEF1 [$0489W] #Easy Down Dart (At $ED79)
%patch $EEF3 [$0489W] #Easy Left Dart (At $ED79)
%patch $EF21 [$0463W] #Medium Up Dart (At $ED53)
%patch $EF23 [$0463W] #Medium Right Dart (At $ED53)
%patch $EF25 [$0463W] #Medium Down Dart (At $ED53)
%patch $EF27 [$0463W] #Medium Left Dart (At $ED53)
%patch $EF29 [$043DW] #Hard Up Dart (At $ED2D)
%patch $EF2B [$043DW] #Hard Right Dart (At $ED2D)
%patch $EF2D [$043DW] #Hard Down Dart (At $ED2D)
%patch $EF2F [$043DW] #Hard Left dart (At $ED2D)
Dart Gun Initiation code
#Dart shooter - hard
%patch $ED2D $83 $3E [$7A6CW] {$02 $7D} $03 $E9 $00C6W $8B $46 $F8 $05 $FFADW
$50 $FF $76 $FC $57 $9A {$11A20E3BRL} $83 $C4 $06 $C7
$06 $CB79W $0001W $E9 $00AAW
#Dart shooter - medium
%patch $ED53 $83 $3E [$7A6CW] {$02 $7D} $03 $E9 $00A0W $8B $46 $F8 $05 $FFB1W
$50 $FF $76 $FC $57 $9A {$11A20E3BRL} $83 $C4 $06 $C7 $06 $CB79W
$0001W $E9 $0084W
#Dart shooter - easy
%patch $ED79 $8B $46 $F8 $05 $FFCBW $50 $FF $76 $FC $57 $9A {$11A20E3BRL}
$83 $C4 $06 $C7 $06 $CB79W $0001W $EB $69
#Dart shooter spawning code
%patch $1285B $55 $8B $EC $56 $8B $76 $0A $33 $C0 $50 $9A $06BD1E11RL $83
$C4 $02 $8B $1E $D8 $A7 $C7 $07 [$0001W] $C7 $47 $02 [$0001W] $8B
$46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $C7 $47 $06 [$0000W] $8B $46
$08 $D3 $E0 $89 $47 $0C $89 $77 $3E $8B $DE $83 $FB [$03] $77 $50
$D1 $E3 $2E $FF $A7 {$0EDEW} $8B $1E $D8 $A7 $83 {$6F $0C} [$30] $81
{$47 $0A} [$0090W] $C7 {$47 $1E} [$017CW] $EB $35 $8B $1E $D8 $A7 $81
{$47 $0A} [$0080W] $83 {$47 $0C} [$50] $C7 {$47 $1E} [$0180W] $EB $21 $8B
$1E $D8 $A7 $81 {$47 $0A} [$0090W] $C7 {$47 $1E} [$017EW] $EB $11 $8B
$1E $D8 $A7 $83 {$47 $0C} [$70] $83 {$6F $0A} [$30] $C7 {$47 $1E} [$0182W]
$B8 [$3962W] $50 $FF $36 $D8 $A7 $9A $09DC118CRL $83 $C4 $04
$5E $5D $CB
#Dart shooter position list
%patch $128FE $0E82W #Up (At $128A2)
%patch $12900 $0E96W #Right (At $128B6)
%patch $12902 $0EAAW #Down (At $128CA)
%patch $12904 $0EBAW #Left (At $128DA)