This is part 1 of DataMaster's domain's cog scripting tutorials. It has been mirrored here for archival purposes. You can find sample scripts, programs and further documentation here. You can find parts two and three also on moddb.
Chapter 1
Introduction
Welcome to the DataMaster's Jedi Knight programming tutorial. In this tutorial, we'll start off with a basic understanding of Jedi Knight and then get to scripting concepts. After that we'll go on to basic syntax and writing cogs. And in the third chapter, we'll get to the stuff that most people never understand. Cog is a very simple language to learn, and if you read carefully, you'll understand most of what you need to start hacking into JK by the time you're done.
It doesn't matter if you have programming experience or not, but if you do - especially anything related to C++, Cog will be even easier for you to understand. The hardest thing is not learning the syntax - it's getting a fundamental understanding of the way JK works.
Cog Basics
Cog Files
Cog files are just regular text files with a .cog extension. Jedi Knight will look for cog files in a resource subfolder named cog. This folder can be in several different places - which we'll cover later on.
It's easy to think of a "cog" as a simple piece of text. But text won't do anything by itself. When JK loads a level and all the cogs needed for it, these cogs are stored in memory. When JK needs to use one of them, it reads the information it loaded from the cog file and performs whatever instructions the cog contained. The point is that the cog does nothing - it is simply a text file that JK interprets when it needs to.
Each time JK finds a entry for a cog file, it will load that cog into memory. It doesn't matter if there's more than entry for a cog - multiple copies of a cog can run in memory with no connection to each other.
Events
Cogscripts are event based. An event happens in the game, and JK looks for code to run for that event. There may or may not be code for that event, and for some events JK doesn't bother using cogs. But every cog works by associating itself with either some part of the level or an object in it. When something happens to one of the cog's associated objects, JK will process the event and look for corresponding code in that cog.
Cogs are often called cogscripts (or just scripts) because in programming, a script is interpreted code with subroutines that are run when events occur. An event that has a subroutine assigned to it is called a scripted event. You should be able to see how the term "script" has been borrowed from it's meaning in theatrical plays.
Cog Types
There are three different types of cogs: level, class, and inventory cogs. They're all scripts and have the same syntax, but JK uses them for different things. Level cogs are loaded by a jedi knight level file (or jkl). This file contains all of the level's geometry and listings for every type of resource that JK needs to load the level. Level cogs are usually loaded to control specific objects in the game like elevators and doors.
Class cogs are also listed in the jkl file, but in a different section. Whereas level cogs are loaded to control specific things that will be in the level, class cogs are assigned to types of things like players, stormtroopers, and grenades. Class cogs may control many objects in the game at once.
Inventory or items cogs are loaded by the items.dat file. The items.dat is responsible for remembering what items your player "owns" while he's in a level. And inventory cogs control these items. Your weapons, items, force powers, and shields are all listed in the items.dat and controlled by inventory cogs.
JK Level Files
A Jedi Knight Level File (jkl) contains all of the information JK needs to create the level architecture and listings of all of the other resources that it needs to load - such as cogs, textures, models, etc. JKLs are important to cogging because they're responsible for loading level and class cogs. So you'll need to be familiar with the basics of a .jkl file.
There are two types of JKLs: level JKLs which are stored in the gob files in the episode folder, and the static.jkl which is stored in the res2 gob in the resource folder. Level JKLs are typical JKL files with level information, but the static.jkl is mostly empty and is loaded with every level. This makes the static.jkl ideal for editing purposes.
JKLs are divided into sections that begin with a "section" keyword and end with an "end" keyword. There are a lot of sections, but only three are important to us: cogscripts, cogs, and templates. It's ambigous to have both a cogscripts and a cogs section, but JK does use them for different purposes. Cogscripts is a listing of all the cogs that the level needs to load, and cogs is a listing of all the cogs that the level will pass values to.
A typical level JKL can be well over 40,000 lines, so there's only an outline of one below. But that's really all we need to go over:
#********** World file D:\Jedi\Products\JK\RELEASE\Episode\JK1\Jkl\01narshadda.jkl ***** Created 9/2/1997 10:21am **********
###### JK information ######
SECTION: JK
# Jedi Knight specific data
################################
#### Copyright information #####
SECTION: COPYRIGHT
................................
................@...@...@...@...
.............@...@..@..@...@....
................@.@.@.@.@.@.....
@@@@@@@@......@...........@.....
@@@@@@@@....@@......@@@....@....
@@.....@.....@......@@@.....@@..
@@.@@@@@......@.....@@@......@@.
@@@@@@@@.......@....@@.....@@...
@@@@@@@@.........@@@@@@@@@@.....
@@@@@@@@..........@@@@@@........
@@.....@..........@@@@@.........
@@.@@@@@.........@@@@@@.........
@@.....@.........@@@@@@.........
@@@@@@@@.........@@@@@@.........
@@@@@@@@.........@@@@@@@........
@@@...@@.........@@@@@@@........
@@.@@@.@.........@.....@........
@@..@..@........@.......@.......
@@@@@@@@........@.......@.......
@@@@@@@@.......@........@.......
@@..@@@@.......@........@.......
@@@@..@@......@.........@.......
@@@@.@.@......@.........@.......
@@....@@........................
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@.@@@@@@@@@@@@@@@@@@
@@.@@..@@@@@..@@@@@@@@@@.@@@@@@@
@@.@.@.@@@@.@.@@@.@..@@...@@@..@
@@..@@@@@@....@@@..@@@@@.@@@@.@@
@@@@@@@@...@@.@@@.@@@@@..@@...@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@.copyright.(c).1997.lucasarts.@
@@@@@@..entertainment.co..@@@@@@
################################
###### Header information ######
SECTION: HEADER
# version and global constant settings
Version 1
World Gravity 4.00
Ceiling Sky Z 20.000000
Horizon Distance 200.000000
Horizon Pixels per Rev 768.000000
Horizon Sky Offset 0.000000 0.000000
Ceiling Sky Offset 0.000000 0.000000
MipMap Distances 1.000000 2.000000 3.000000 4.000000
LOD Distances 0.300000 0.600000 0.900000 1.200000
Perspective distance 2.00
Gouraud distance 2.00
################################
###### Sound information ######
SECTION: SOUNDS
World sounds 245
example.wav
end
################################
##### Material information #####
SECTION: MATERIALS
World materials 560
#num: mat: xTile: yTile:
0: example.mat 1.000000 1.000000
end
################################
#### Geomtry Resources Info ####
SECTION: GEORESOURCE
#------ Palette Subsection -----
World Colormaps 2
0: example.cmp
#----- Vertices Subsection -----
World vertices 4360
#num: vertex:
0: 5.299998 6.699994 7.199998
#-- Texture Verts Subsection ---
World texture vertices 10574
#num: u: v:
0: 135.000061 137.999893
#------ Adjoins Subsection -----
World adjoins 1206
#num: flags: mirror: dist:
0: 0x7 50 2.00
#----- Surfaces Subsection -----
World surfaces 4595
#num: mat: surfflags: faceflags: geo: light: tex: adjoin: extralight: nverts: vertices: intensities:
0: 410 0x4 0x0 4 3 1 -1 0.00 7 0,0 1,1 2,2 3,3 4,4 5,5 6,6 0.577673 0.118668 0.741789 1.162032 0.992560 0.175367 0.947318
#--- Surface normals ---
0: 0.000000 1.000000 0.000000
################################
###### Sector information ######
Section: SECTORS
World sectors 462
SECTOR 0
FLAGS 0x0
AMBIENT LIGHT 0.37
EXTRA LIGHT 0.00
COLORMAP 0
TINT 0.00 0.00 0.00
BOUNDBOX 4.899998 6.699994 5.299998 5.699998 10.700008 7.599998
CENTER 5.299998 8.700001 6.449998
RADIUS 2.341480
VERTICES 55
0: 6
1: 5
2: 4
3: 2
4: 1
5: 0
6: 7
7: 8
8: 9
9: 10
10: 11
11: 12
12: 15
13: 43
14: 16
15: 46
16: 17
17: 48
18: 18
19: 51
20: 19
21: 53
22: 20
23: 22
24: 44
25: 49
26: 50
27: 52
28: 54
29: 21
30: 42
31: 14
32: 26
33: 41
34: 27
35: 40
36: 28
37: 39
38: 29
39: 38
40: 30
41: 37
42: 31
43: 36
44: 32
45: 35
46: 33
47: 34
48: 25
49: 3
50: 13
51: 23
52: 24
53: 45
54: 47
SURFACES 0 30
######### AI Classes ###########
Section: AICLASS
World AIClasses 16
0: example.ai
end
################################
###### Models information ######
Section: MODELS
World models 122
0: example.3do
end
################################
###### Sprite information ######
Section: SPRITES
World sprites 18
0: example.spr
end
################################
##### Keyframe information #####
Section: KEYFRAMES
World keyframes 201
0: example.key
end
################################
###### Animation Classes #######
Section: ANIMCLASS
World puppets 12
0: ky.pup
end
################################
#### Sound (foley) Classes #####
Section: Soundclass
World soundclasses 42
0: example.snd
end
################################
########## COG scripts #########
Section: cogscripts
World scripts 65
0: example.cog
end
################################
######### COG placement ########
Section: cogs
World cogs 91
#Num Script Symbol values
0: example.cog 4 -1 -1 -1 8.000000 2.000000 0.500000
end
################################
##### Templates information ####
Section: TEMPLATES
World templates 210
#Name: Based On: Params:
_actor none orient=(0.000000/0.000000/0.000000) type=actor collide=1 move=physics thingflags=0x20000000 mass=150.000000 physflags=0x4a4f maxrotvel=200.000000 maxvel=1.000000 health=40.00 maxhealth=40.00 maxrotthrust=180.00 jumpspeed=1.50 eyeoffset=(0.000000/0.000000/0.037000) minheadpitch=-80.00 maxheadpitch=80.00 lightoffset=(0.000000/0.070000/0.040000) lightintensity=0.80
walkplayer _actor type=player thingflags=0x20000401 light=0.200000 model3d=ky.3do size=0.065000 movesize=0.065000 puppet=ky.pup soundclass=ky.snd cog=kyle.cog surfdrag=3.000000 airdrag=0.500000 staticdrag=0.300000 health=100.00 maxhealth=100.00 maxthrust=2.00 typeflags=0x1 error=0.50 fov=0.71 chance=1.00
end
################################
######## Thing placement #######
Section: Things
World things 552
#num template: name: X: Y: Z: Pitch: Yaw: Roll: Sector:
0: walkplayer walkplayer -10.443433 -5.455094 -1.129886 0.000000 -59.994259 0.000000 339
end
################################
You can see that each section begins with Section: name and ends with end. The line directly under the section name tells JK how many things will be in the list (e.g., world things 552). In this example, all of the world counts haven't been changed, but in a real JKL, the world count must match (or exceed for some sections) the number of items in the list below.
In the cog section, the example cog has a list of numbers after it. These numbers are variables that the level is giving to the cog. Most level cogs are fairly generic - they'll work with any level, but they needd a few key variables. Let's say you're adding an elevator cog to your level. The cog will need to know the thing number (the number of the thing in the thing section) of the elevator, how quickly you want the elevator to move, how many stopping points the elevator will have, and other things like that. Level cogs will leave these variables open for the level to define. And by listing these values after the cogs definition, the level is assigning values to the variables left open for it. In the next chapter, when you see how the cog leaves these variables open, it should make more sense.
The world things number is important to us because it is the limit on how many things we can create in the level. The most the thing limit should be is 600 - going over that is usually unstable.
The static.jkl is short enough that nothing has to be abbreviated, so we'll review it as it is:
#********** World file D:\jedi\Products\JK\Release\Jkl\static.jkl ***** Created 10/30/1996 6:32pm **********
#### Copyright information #####
SECTION: COPYRIGHT
................................
................@...@...@...@...
.............@...@..@..@...@....
................@.@.@.@.@.@.....
@@@@@@@@......@...........@.....
@@@@@@@@....@@......@@@....@....
@@.....@.....@......@@@.....@@..
@@.@@@@@......@.....@@@......@@.
@@@@@@@@.......@....@@.....@@...
@@@@@@@@.........@@@@@@@@@@.....
@@@@@@@@..........@@@@@@........
@@.....@..........@@@@@.........
@@.@@@@@.........@@@@@@.........
@@.....@.........@@@@@@.........
@@@@@@@@.........@@@@@@.........
@@@@@@@@.........@@@@@@@........
@@@...@@.........@@@@@@@........
@@.@@@.@.........@.....@........
@@..@..@........@.......@.......
@@@@@@@@........@.......@.......
@@@@@@@@.......@........@.......
@@..@@@@.......@........@.......
@@@@..@@......@.........@.......
@@@@.@.@......@.........@.......
@@....@@........................
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@.@@@@@@@@@@@@@@@@@@
@@.@@..@@@@@..@@@@@@@@@@.@@@@@@@
@@.@.@.@@@@.@.@@@.@..@@...@@@..@
@@..@@@@@@....@@@..@@@@@.@@@@.@@
@@@@@@@@...@@.@@@.@@@@@..@@...@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@.copyright.(c).1997.lucasarts.@
@@@@@@..entertainment.co..@@@@@@
################################
###### Header information ######
SECTION: HEADER
# version and global constant settings
Version 1
World Gravity 4.00
Ceiling Sky Z 3.000000
Horizon Distance 100.000000
Horizon Pixels per Rev 768.000000
Horizon Sky Offset 0.000000 0.000000
Ceiling Sky Offset 0.000000 0.000000
MipMap Distances 1.000000 2.000000 3.000000 4.000000
LOD Distances 0.300000 0.600000 0.900000 1.200000
Perspective distance 2.00
Gouraud distance 2.00
################################
###### Sound information ######
SECTION: SOUNDS
World sounds 60
end
################################
##### Material information #####
SECTION: MATERIALS
World materials 160
end
################################
Section: Soundclass
World soundclasses 1
0: ky.snd
end
###### Models information ######
Section: MODELS
World models 32
0: bryv.3do
1: bryg.3do
2: sabv.3do
3: sabg.3do
4: rldv.3do
5; rldg.3do
6: conv.3do
7: cong.3do
8: strv.3do
9: strg.3do
10: rptv.3do
11: rptg.3do
12: detv.3do
13: detg.3do
14: seqv.3do
15: seqg.3do
16: fistv.3do
17: fistg.3do
18: bowv.3do
19: bowg.3do
20: ky.3do
21: bry0.3do
22: con0.3do
23: dflt.3do
24: rep0.3do
25: det0.3do
26: seqp.3do
27: rld0.3do
end
################################
###### Sprite information ######
Section: SPRITES
World sprites 20
0: bryx.spr
1: detx.spr
2: bowx2.spr
3: bowx.spr
4: rptx.spr
5: seqx2.spr
6: debrisx.spr
7: rldx.spr
8: conx.spr
end
################################
##### Keyframe information #####
Section: KEYFRAMES
World keyframes 128
end
################################
###### Animation Classes #######
Section: ANIMCLASS
World puppets 16
0: ky.pup
end
################################
########## COG scripts #########
Section: cogscripts
World scripts 50
end
################################
######### COG placement ########
Section: cogs
World cogs 50
#Num Script Symbol values
end
################################
Notice that the static.jkl is missing a lot of sections. That's because the static.jkl was originally intended to load only the standard resources that every level would use.
The great thing about this file is that we can add a template section to it. We can also add cogs and some of the other resource files. This allows us to load resources and templates for a patch without having to change the level JKL.
Templates
Templates are JK's blueprints for creating objects in the game. Every object you see in the game (and many you don't) is created from a template stored in either the level's .jkl file or the static.jkl. With templates in a JKL file, we can create things from them in the game with a cog. Here's what the template section of the first Narshaada level looks like:
##### Templates information ####
Section: TEMPLATES
World templates 210
#Name: Based On: Params:
_actor none orient=(0.000000/0.000000/0.000000) type=actor collide=1 move=physics thingflags=0x20000000 mass=150.000000 physflags=0x4a4f maxrotvel=200.000000 maxvel=1.000000 health=40.00 maxhealth=40.00 maxrotthrust=180.00 jumpspeed=1.50 eyeoffset=(0.000000/0.000000/0.037000) minheadpitch=-80.00 maxheadpitch=80.00 lightoffset=(0.000000/0.070000/0.040000) lightintensity=0.80
walkplayer _actor type=player thingflags=0x20000401 light=0.200000 model3d=ky.3do size=0.065000 movesize=0.065000 puppet=ky.pup soundclass=ky.snd cog=kyle.cog surfdrag=3.000000 airdrag=0.500000 staticdrag=0.300000 health=100.00 maxhealth=100.00 maxthrust=2.00 typeflags=0x1 error=0.50 fov=0.71 chance=1.00
_decor none orient=(0.000000/0.000000/0.000000) type=cog collide=1 move=path
_structure _decor collide=3 thingflags=0x8
_walkstruct _structure thingflags=0x400048
2x8catwalk _walkstruct model3d=c2x8.3do size=0.412822 movesize=0.412822
4x4elev _walkstruct model3d=e4x4.3do size=0.336311 movesize=0.336311 soundclass=med_elev.snd
_humanactor _actor size=0.065000 movesize=0.065000 surfdrag=3.000000 airdrag=0.500000 maxvel=0.500000 maxthrust=0.80 typeflags=0x80000
_weapon none orient=(0.000000/0.000000/0.000000) type=weapon collide=1 move=physics thingflags=0x20000000 timer=10.000000 mass=5.000000 physflags=0x200 maxrotvel=90.000000 damageclass=0x2 typeflags=0x1
_explosion none orient=(0.000000/0.000000/0.000000) type=explosion typeflags=0x1 damageclass=0x4
+laserhit _explosion thingflags=0x1 light=0.200000 timer=0.500000 sprite=bryx.spr soundclass=exp_laserhit.snd typeflags=0x33 blasttime=0.300000 maxlight=0.400000
+smflash _explosion thingflags=0x1 light=0.400000 timer=0.100000 typeflags=0x0
+laserfleshhit +laserhit soundclass=exp_fleshy.snd
+bryarbolt _weapon thingflags=0x20000001 light=0.400000 model3d=bry0.3do size=0.001000 movesize=0.001000 soundclass=bry.snd creatething=+smflash maxrotvel=0.000000 vel=(0.000000/4.000000/0.000000) explode=+laserhit fleshhit=+laserfleshhit damage=30.000000 mindamage=10.000000 typeflags=0x20440d rate=15.000000
+stlaser +bryarbolt model3d=str0.3do soundclass=stlaser.snd vel=(0.000000/6.000000/0.000000) rate=10.000000
+elaser +stlaser vel=(0.000000/4.000000/0.000000) damage=12.000000 mindamage=5.000000
reeyeesgun _humanactor thingflags=0x20000400 model3d=rystr.3do size=0.072900 movesize=0.072900 puppet=rystr.pup soundclass=rystr.snd cog=actor_rb.cog weapon=+elaser health=50.00 maxhealth=50.00 maxthrust=0.90 maxrotthrust=70.00 jumpspeed=1.20 typeflags=0x1 fireoffset=(0.014700/0.080000/0.034000) aiclass=rydefault.ai
2x3door _structure model3d=d2x3.3do size=0.180710 movesize=0.180710 soundclass=sm_door.snd
3x10catwalk _walkstruct model3d=c3x10.3do size=0.522160 movesize=0.522160
crate4_3 _walkstruct model3d=crt4-3.3do size=0.173196 movesize=0.173196
crane _decor thingflags=0x400 model3d=cran.3do size=0.075000 movesize=0.075000 cog=xcrane.cog
funicular _walkstruct model3d=01func.3do size=0.369225 movesize=0.369225 soundclass=funicular.snd
crate6_2 _walkstruct thingflags=0x400448 model3d=crt6-2.3do size=0.087201 movesize=0.087201 cog=actor_cr.cog
console2 _walkstruct model3d=con2.3do size=0.073806 movesize=0.073806
_ghoststructure _structure collide=0
2x3jam _ghoststructure model3d=j2x3.3do size=0.268712 movesize=0.268712
6x6elev_1 _walkstruct model3d=e6x6_1.3do size=1.180995 movesize=1.180995 soundclass=lg_elev.snd
crate4_1 _walkstruct model3d=crt4-1.3do size=0.051962 movesize=0.051962
crate4_2 _walkstruct model3d=crt4-2.3do size=0.086602 movesize=0.086602
+whitecloud none orient=(0.000000/0.000000/0.000000) type=particle timer=0.200000 typeflags=0x3f material=00gsmoke.mat range=0.020000 rate=128.000000 maxthrust=30.000000 elementsize=0.007000 count=128
+dustcloud +whitecloud timer=0.120000 material=dusty.mat range=0.015000 rate=256.000000 maxthrust=80.000000 elementsize=0.010000
+punchcloud +dustcloud timer=0.150000 material=00gsmoke.mat range=0.006000 rate=64.000000 maxthrust=4.000000 elementsize=0.004000 count=16
+punch_exp _explosion timer=0.001000 soundclass=exp_punch.snd creatething=+punchcloud typeflags=0x0
+punch _weapon size=0.001000 movesize=0.001000 mass=50.000000 explode=+punch_exp fleshhit=+punch_exp damage=20.000000 damageclass=0x1 typeflags=0x200d range=0.150000 force=50.000000
+ry_punch +punch damage=10.000000 force=25.000000
reeyeesfist _humanactor thingflags=0x20000400 model3d=ry.3do size=0.072900 movesize=0.072900 puppet=ryfist.pup soundclass=ryfist.snd cog=actor_rf.cog weapon=+ry_punch health=50.00 maxhealth=50.00 maxthrust=1.00 maxrotthrust=70.00 jumpspeed=1.20 typeflags=0x20001 aiclass=rypundefault.ai
_droidactor _humanactor typeflags=0x80140
powerdroid _droidactor thingflags=0x20000400 model3d=pd.3do size=0.080000 movesize=0.080000 puppet=pd.pup soundclass=gonk.snd cog=actor_go.cog mass=180.000000 health=50.00 maxhealth=50.00 maxthrust=0.20 maxrotthrust=50.00 typeflags=0x180140 aiclass=gonk.ai
_powerup none orient=(0.000000/0.000000/0.000000) type=item collide=1 move=physics size=0.100000 movesize=0.010000 surfdrag=3.000000 airdrag=1.000000 mass=10.000000 height=0.050000 physflags=0x400000 angvel=(0.000000/90.000000/0.000000) typeflags=0x1 respawn=30.000000
shieldrecharge _powerup thingflags=0x400 model3d=shld.3do cog=pow_shields.cog
3x3door_1 _walkstruct model3d=d3x3_1.3do size=0.262464 movesize=0.262464 soundclass=sm_door.snd
_ghostdecor _decor collide=0
light1.0 _ghostdecor thingflags=0x1 light=1.000000
ghostshuttle _ghostdecor model3d=shut.3do size=1.000000 movesize=1.000000
fan1 none orient=(0.000000/0.000000/0.000000) type=cog collide=1 move=physics model3d=fan1.3do size=0.005000 movesize=0.005000 physflags=0x200 maxrotvel=90.000000 angvel=(0.000000/90.000000/0.000000)
roofvent3 _walkstruct model3d=01rfd3.3do size=0.249375 movesize=0.249375
roofvent2 _walkstruct model3d=01rfd2.3do size=0.226595 movesize=0.226595
roofpipe _ghostdecor model3d=01rfd0.3do size=0.077027 movesize=0.077027
4x3door_1 _structure model3d=d4x3_1.3do size=0.250312 movesize=0.250312 soundclass=med_door.snd
reeyeesbhfist reeyeesfist model3d=rh.3do health=60.00 maxhealth=60.00 maxrotthrust=85.00
reeyeesbhgun reeyeesgun model3d=rhstr.3do health=60.00 maxhealth=60.00 maxrotthrust=80.00 aiclass=rybdefault.ai
healthpack _powerup thingflags=0x408 model3d=hepk.3do cog=pow_health.cog
strifle _powerup thingflags=0x400 model3d=strp.3do cog=pow_strifle.cog
2x2elev _walkstruct model3d=e2x2_0.3do size=0.192295 movesize=0.192295 soundclass=sm_elev.snd
3x8catwalk _walkstruct model3d=c3x8.3do size=0.427378 movesize=0.427378
energycell _powerup thingflags=0x400 model3d=ecel.3do cog=pow_energy.cog
greedopistol _powerup thingflags=0x400 model3d=ggun.3do cog=pow_bryar.cog
+ebolt +bryarbolt model3d=bry1.3do vel=(0.000000/3.500000/0.000000) damage=10.000000 mindamage=5.000000
greedo _humanactor thingflags=0x20000400 model3d=gr.3do size=0.061500 movesize=0.061500 puppet=gr.pup soundclass=gr.snd cog=actor_gr.cog mass=70.000000 maxvel=0.300000 weapon=+ebolt maxrotthrust=80.00 typeflags=0x2080001 fireoffset=(0.016000/0.055000/0.004000) aiclass=grdefault.ai
bactatank _powerup thingflags=0x400 model3d=bact.3do cog=pow_bacta.cog respawn=60.000000
_civilian _humanactor surfdrag=2.000000 mass=100.000000 maxvel=0.300000 maxthrust=2.00 maxrotthrust=90.00 typeflags=0x180000
man2 _civilian thingflags=0x20000400 model3d=m2.3do size=0.060000 movesize=0.060000 puppet=m2.pup soundclass=mn1.snd cog=actor_pm.cog maxvel=0.200000 health=50.00 maxhealth=50.00 maxthrust=0.50 maxrotthrust=60.00 aiclass=peddefault.ai
nman2 man2 cog=actor_mn.cog aiclass=pednarsh.ai
crate4_4 _walkstruct model3d=crt4-4.3do size=0.259810 movesize=0.259810
crate6_1 _walkstruct thingflags=0x400448 model3d=crt6-1.3do size=0.045598 movesize=0.045598 cog=actor_cs.cog
man1 _civilian thingflags=0x20000400 model3d=mn.3do size=0.060000 movesize=0.060000 puppet=mn.pup soundclass=mn1.snd cog=actor_pm.cog maxvel=0.200000 health=50.00 maxhealth=50.00 maxthrust=0.50 maxrotthrust=60.00 aiclass=peddefault.ai
nman1 man1 cog=actor_mn.cog aiclass=pednarsh.ai
woman1 _civilian thingflags=0x20000400 model3d=wm.3do size=0.056000 movesize=0.056000 puppet=wm.pup soundclass=wm1.snd cog=actor_pf.cog maxvel=0.200000 health=50.00 maxhealth=50.00 maxthrust=0.50 maxrotthrust=60.00 aiclass=peddefault.ai
nwoman1 woman1 cog=actor_fn.cog aiclass=pednarsh.ai
goggles _powerup thingflags=0x400 model3d=gogl.3do cog=pow_goggles.cog respawn=60.000000
freighter _ghoststructure model3d=01frt.3do size=7.945067 movesize=7.945067
r5 _droidactor thingflags=0x20000400 model3d=r5.3do size=0.036000 movesize=0.036000 puppet=r5.pup soundclass=r2.snd cog=actor_r5.cog maxvel=0.400000 health=50.00 maxhealth=50.00 maxthrust=0.40 maxrotthrust=50.00 typeflags=0x180140 aiclass=drdefault.ai
smbp _powerup thingflags=0x400 model3d=bpck.3do cog=pow_smbkpk.cog
_zwalkstruct _structure thingflags=0x400040
tiebomber _zwalkstruct model3d=tieb.3do size=0.500000 movesize=0.500000 puppet=cr.pup
3x3elev _walkstruct model3d=e3x3.3do size=0.209751 movesize=0.209751 soundclass=sm_elev.snd
8t88 _humanactor model3d=8t.3do size=0.060000 movesize=0.060000 puppet=8t.pup soundclass=8t.snd mass=300.000000 health=10000.00 maxhealth=10000.00 maxrotthrust=70.00 typeflags=0x100 aiclass=default.ai
00table _walkstruct thingflags=0x48 model3d=00tabl.3do size=0.070420 movesize=0.070420
column01 _structure model3d=01colm.3do size=0.204987 movesize=0.204987
nbartender nman2 cog=actor_bt.cog
tuskensoused _ghostdecor move=none model3d=thout.3do size=0.227490 movesize=0.227490 puppet=cr.pup
ghost none orient=(0.000000/0.000000/0.000000) type=ghost move=path
fullshield _powerup thingflags=0x400 model3d=vest.3do cog=pow_vest.cog respawn=60.000000
10x10door _walkstruct model3d=d10x10.3do size=1.169825 movesize=1.169825 soundclass=lg_elev.snd
detonator _powerup thingflags=0x400 model3d=detp.3do cog=pow_thermal.cog
bottle04 _structure model3d=bottle4.3do size=0.080942 movesize=0.080942
+firecloud +dustcloud material=00explosion.mat range=0.050000 rate=64.000000 maxthrust=40.000000 count=64
+grenade_exp _explosion thingflags=0x1 light=0.200000 timer=0.800000 sprite=detx.spr soundclass=exp_det.snd creatething=+firecloud typeflags=0x17 damage=75.000000 blasttime=0.700000 force=100.000000 maxlight=0.800000 range=0.450000
+remote_exp +grenade_exp sprite=debrisx.spr soundclass=exp_remote.snd damage=0.000000 force=25.000000
+mouse_exp +remote_exp force=10.000000
mousebot _droidactor thingflags=0x20000400 model3d=mb.3do size=0.039000 movesize=0.039000 soundclass=mousebot.snd cog=actor_mb.cog mass=20.000000 height=0.040000 health=10.00 maxthrust=1.00 maxrotthrust=80.00 typeflags=0x20 explode=+mouse_exp aiclass=mouse.ai
+grenade2 _weapon timer=3.000000 model3d=det0.3do size=0.014895 movesize=0.014895 soundclass=det.snd surfdrag=3.000000 airdrag=0.800000 mass=1.000000 physflags=0x225 vel=(0.000000/2.000000/1.500000) angvel=(90.000000/45.000000/90.000000) buoyancy=0.250000 explode=+grenade_exp fleshhit=+grenade_exp damageclass=0x4 typeflags=0x40309
+grenade1 +grenade2 timer=10.000000 typeflags=0x4030d
+crossbowhit +laserhit sprite=bowx2.spr soundclass=exp_bowhit.snd
+lgflash _explosion thingflags=0x1 light=0.300000 timer=0.400000 typeflags=0x12 blasttime=0.200000 maxlight=1.000000
+crossbowbolt _weapon thingflags=0x20000001 light=0.500000 model3d=bow0.3do size=0.005000 movesize=0.005000 soundclass=bow.snd creatething=+lgflash vel=(0.000000/5.000000/0.000000) angvel=(0.000000/0.000000/120.000000) explode=+crossbowhit fleshhit=+crossbowhit damage=60.000000 mindamage=20.000000 damageclass=0x4 typeflags=0x20440d rate=10.000000
+crossbowhit2 _explosion thingflags=0x1 light=0.200000 timer=0.500000 sprite=bowx.spr typeflags=0x33 blasttime=0.300000 maxlight=0.400000
+crossbowbolt2 +crossbowbolt model3d=bow1.3do soundclass=none creatething=none explode=+crossbowhit2 fleshhit=+crossbowhit2 damage=40.000000 typeflags=0x440d
+crossbowbolt3 +crossbowbolt typeflags=0x28440d
+repeaterhit +laserhit sprite=rptx.spr soundclass=exp_rpthit.snd
+rpt_sparks none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.700000 mass=0.100000 physflags=0x400201 vel=(0.000000/0.000000/0.200000) typeflags=0x27 material=sparky.mat range=0.040000 rate=24.000000 maxthrust=7.000000 elementsize=0.005000 count=24
+rptfleshhit _explosion thingflags=0x1 light=0.100000 timer=0.800000 soundclass=exp_fleshy.snd creatething=+rpt_sparks typeflags=0x12 blasttime=0.700000 maxlight=0.300000
+repeaterball _weapon thingflags=0x20000001 light=0.300000 model3d=rpt0.3do size=0.005000 movesize=0.005000 soundclass=rep.snd creatething=+smflash vel=(0.000000/6.000000/0.000000) explode=+repeaterhit fleshhit=+rptfleshhit damage=20.000000 mindamage=5.000000 typeflags=0x440d rate=20.000000
+firecloud2 +firecloud elementsize=0.012500
+firecloud3 +firecloud maxthrust=20.000000 count=32
+debris_exp _explosion timer=1.000000 sprite=debrisx.spr soundclass=exp_small.snd creatething=+firecloud3 typeflags=0x7 blasttime=0.500000
_debris none orient=(0.000000/0.000000/0.000000) type=weapon collide=1 move=physics timer=1.100000 airdrag=3.000000 physflags=0x201 vel=(0.000000/4.000000/0.000000) angvel=(5.000000/10.000000/0.000000) explode=+debris_exp damage=5.000000 damageclass=0x1 typeflags=0xc
_debris2 _debris explode=+smflash
shrapnel2_1 _debris2 model3d=shrp_1.3do size=0.045000 movesize=0.045000
shrapnel2_2 _debris2 model3d=shrp_2.3do size=0.040000 movesize=0.040000
shrapnel2_3 _debris2 model3d=shrp_3.3do size=0.028000 movesize=0.028000
shrapnel2_4 _debris2 model3d=shrp_4.3do size=0.026000 movesize=0.026000
+sequencer_exp _explosion thingflags=0x1 light=0.200000 timer=0.800000 sprite=seqx2.spr soundclass=exp_med.snd creatething=+firecloud2 typeflags=0x17 damage=100.000000 blasttime=0.700000 force=300.000000 maxlight=0.800000 range=0.600000 debris=shrapnel2_1 debris=shrapnel2_2 debris=shrapnel2_3 debris=shrapnel2_4
+seqchrg +grenade2 timer=1.000000 model3d=seq0.3do size=0.010000 movesize=0.010000 soundclass=seq.snd surfdrag=5.000000 airdrag=1.000000 physflags=0x29d vel=(0.000000/0.100000/0.000000) angvel=(0.000000/0.000000/0.000000) buoyancy=0.150000 explode=+sequencer_exp fleshhit=+sequencer_exp typeflags=0x40380
+seqchrg2 +seqchrg thingflags=0x20000400 timer=60.000003 cog=class_sequencer.cog
shrapnel_1 _debris model3d=shrp_1.3do size=0.045000 movesize=0.045000
shrapnel_2 _debris model3d=shrp_2.3do size=0.040000 movesize=0.040000
shrapnel_3 _debris model3d=shrp_3.3do size=0.028000 movesize=0.028000
shrapnel_4 _debris model3d=shrp_4.3do size=0.026000 movesize=0.026000
+raildet_exp _explosion thingflags=0x1 light=0.200000 timer=0.500000 sprite=rldx.spr soundclass=exp_raildet.snd typeflags=0x17 damage=110.000000 blasttime=0.700000 force=300.000000 maxlight=0.800000 range=0.500000 debris=shrapnel_1 debris=shrapnel_2 debris=shrapnel_3 debris=shrapnel_4
+raildet2 +grenade1 thingflags=0x20000400 timer=2.500000 model3d=rld0.3do size=0.003000 movesize=0.003000 puppet=ra.pup soundclass=rail.snd creatething=+lgflash cog=00_smoketrail.cog airdrag=0.000000 height=0.003000 physflags=0x200 vel=(0.000000/2.500000/0.000000) angvel=(0.000000/0.000000/90.000000) explode=+raildet_exp fleshhit=+raildet_exp damage=5.000000 typeflags=0x240b81
+raildet_exp2 +raildet_exp debris=shrapnel_1 debris=shrapnel_2 debris=shrapnel_3 debris=shrapnel_4
+raildet +raildet2 timer=10.000000 explode=+raildet_exp2 fleshhit=+raildet_exp2 damage=20.000000 typeflags=0x24020d
+conccloud +dustcloud rate=512.000000 maxthrust=100.000000 count=256 minsize=0.012000 pitchrange=5.000000
+conc_exp _explosion thingflags=0x1 light=0.300000 timer=1.000000 sprite=conx.spr soundclass=exp_conc.snd creatething=+conccloud typeflags=0x17 damage=80.000000 blasttime=1.000000 force=200.000000 maxlight=0.800000 range=0.800000
+concbullet _weapon thingflags=0x20000001 model3d=con0.3do size=0.005000 movesize=0.005000 soundclass=conc.snd creatething=+lgflash vel=(0.000000/7.000000/0.000000) explode=+conc_exp fleshhit=+conc_exp damage=20.000000 typeflags=0x20000d
+concblast2p +dustcloud orient=(90.000000/0.000000/0.000000) range=0.001500 rate=128.000000 elementsize=0.005000 count=64 minsize=0.001200 pitchrange=5.000000
+concblast3p +concblast2p typeflags=0x2b material=00ramp4.mat maxthrust=100.000000
+concblast2 _weapon size=0.005000 movesize=0.005000 fleshhit=+concblast3p trailthing=+concblast2p elementsize=0.300000 damage=80.000000 mindamage=20.000000 typeflags=0xa00d range=5.000000 rate=1.000000
+axe_exp _explosion timer=0.001000 soundclass=exp_axe.snd typeflags=0x0
+gamaxe _weapon size=0.001000 movesize=0.001000 mass=100.000000 explode=+axe_exp fleshhit=+axe_exp damage=40.000000 damageclass=0x1 typeflags=0x200d range=0.250000 force=50.000000
+force_repel _explosion thingflags=0x1 light=0.500000 timer=0.400000 soundclass=exp_dest.snd typeflags=0x52 blasttime=0.300000 force=200.000000 maxlight=1.000000 range=0.500000
+force_ltpeice none orient=(0.000000/0.000000/0.000000) type=weapon move=physics timer=0.250000 model3d=ligt2.3do size=0.005000 movesize=0.005000 physflags=0x200 maxrotvel=360.000000 angvel=(0.000000/0.000000/360.000000)
+lightninghit none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.200000 typeflags=0x2b material=00ramp4.mat range=0.020000 rate=16.000000 maxthrust=8.000000 elementsize=0.003000 count=16
+force_lightning _weapon thingflags=0x1 light=0.100000 timer=0.100000 size=0.005000 movesize=0.005000 vel=(0.000000/1.000000/0.000000) angvel=(0.000000/0.000000/360.000000) explode=+lightninghit fleshhit=+lightninghit trailthing=+force_ltpeice elementsize=0.075000 trailcylradius=0.050000 trailrandangle=30.000000 damage=13.000000 damageclass=0x8 typeflags=0x1840d range=1.500000
+force_lightning2 +force_lightning damage=15.000000
+force_lightning3 +force_lightning damage=20.000000
+force_lightning4 +force_lightning damage=25.000000
lightsaber _powerup thingflags=0x400 model3d=sabp.3do cog=pow_saber.cog
+force_saber _weapon thingflags=0x20000001 light=0.100000 timer=1.000000 model3d=sab0.3do size=0.005000 movesize=0.005000 vel=(0.000000/1.000000/0.000000) angvel=(0.000000/150.000000/0.000000) explode=lightsaber fleshhit=lightsaber damage=50.000000 damageclass=0x10 typeflags=0x40d
+force_shield none orient=(0.000000/0.000000/0.000000) type=cog move=physics timer=61.000003 particle=sphere.par angvel=(60.000000/60.000000/60.000000)
+force_blind +dustcloud material=00teleport.mat range=0.050000 rate=32.000000 elementsize=0.003000 minsize=0.020000 pitchrange=1.000000 yawrange=1.000000
+smoke none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.800000 physflags=0x20000 vel=(0.000000/0.000000/0.120000) angvel=(0.000000/90.000000/0.000000) typeflags=0x3e material=00gsmoke.mat range=0.030000 elementsize=0.005000 count=8
+dest_trail +smoke vel=(0.000000/0.000000/0.000000) material=dstructparts.mat
+dest_cloud +firecloud material=dstructparts.mat
+force_dest1 _explosion thingflags=0x1 light=0.100000 timer=0.400000 sprite=destruct8.spr soundclass=exp_dest.snd creatething=+dest_cloud typeflags=0x53 damage=15.000000 damageclass=0x8 blasttime=0.300000 force=100.000000 maxlight=0.500000 range=0.500000
+force_dest2 _explosion thingflags=0x1 light=0.200000 timer=0.600000 sprite=destruct8.spr soundclass=exp_dest.snd creatething=+dest_cloud typeflags=0x53 damage=30.000000 damageclass=0x8 blasttime=0.400000 force=200.000000 maxlight=0.600000 range=1.000000
+force_dest3 _explosion thingflags=0x1 light=0.300000 timer=0.800000 sprite=destruct8.spr soundclass=exp_dest.snd creatething=+dest_cloud typeflags=0x53 damage=45.000000 damageclass=0x8 blasttime=0.500000 force=300.000000 maxlight=0.700000 range=1.500000
+force_dest4 _explosion thingflags=0x1 light=0.400000 timer=1.000000 sprite=destruct8.spr soundclass=exp_dest.snd creatething=+dest_cloud typeflags=0x53 damage=60.000000 damageclass=0x8 blasttime=0.600000 force=400.000000 maxlight=0.800000 range=2.000000
+force_dest_p1 _weapon thingflags=0x20000401 light=0.400000 sprite=forcedstruct_150.spr cog=00_desttrail.cog vel=(0.000000/7.000000/0.000000) explode=+force_dest1 fleshhit=+force_dest1 damage=20.000000 typeflags=0xd
+force_dest_p2 +force_dest_p1 explode=+force_dest2 fleshhit=+force_dest2
+force_dest_p3 +force_dest_p1 explode=+force_dest3 fleshhit=+force_dest3
+force_dest_p4 +force_dest_p1 explode=+force_dest4 fleshhit=+force_dest4
+force_heal none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=2.000000 angvel=(90.000000/90.000000/90.000000) typeflags=0x3f material=00teleport.mat range=0.300000 rate=128.000000 maxthrust=0.010000 elementsize=0.003000 count=128
+heavysmoke +smoke timer=1.600000 range=0.100000 rate=32.000000 count=64
+twinkle none orient=(0.000000/0.000000/0.000000) type=explosion thingflags=0x1 timer=0.500000 sprite=twinkle.spr typeflags=0x11
+sspks_wall none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.100000 mass=0.050000 physflags=0x400201 vel=(0.000000/0.000000/0.150000) typeflags=0x2b material=00ramp1.mat range=0.030000 rate=4.000000 maxthrust=8.000000 elementsize=0.003000 count=48
+ssparks_wall _explosion thingflags=0x1 light=0.300000 timer=0.800000 soundclass=exp_saber_wall.snd creatething=+sspks_wall typeflags=0x112 blasttime=0.700000 maxlight=0.500000 flashrgb=(80/90/80)
+sspks_blood none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.200000 mass=0.100000 physflags=0x400201 vel=(0.000000/0.000000/0.200000) typeflags=0x2b material=00ramp2.mat range=0.040000 rate=4.000000 maxthrust=9.000000 elementsize=0.005000 count=24
+ssparks_blood _explosion thingflags=0x1 light=0.100000 timer=0.800000 soundclass=exp_saber_blood.snd creatething=+sspks_blood typeflags=0x12 blasttime=0.700000 maxlight=0.300000
+sspks_saber none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.300000 mass=0.050000 physflags=0x400200 vel=(0.000000/0.000000/0.100000) typeflags=0x27 material=00teleport.mat range=0.020000 rate=32.000000 maxthrust=8.000000 elementsize=0.003000 count=32
+ssparks_saber _explosion thingflags=0x1 light=0.800000 timer=0.800000 soundclass=exp_saber_saber.snd creatething=+sspks_saber typeflags=0x112 blasttime=0.700000 maxlight=1.000000 flashrgb=(150/160/150)
_droppowerup _powerup timer=30.000001 height=0.011000 physflags=0x41 typeflags=0x0
+backpack _droppowerup thingflags=0x400 model3d=bpck.3do cog=pow_backpack.cog height=0.036337 typeflags=0x4
bryarpistol _powerup thingflags=0x400 model3d=bryp.3do cog=pow_bryar.cog
singledetonator _powerup thingflags=0x400 model3d=detp_1.3do cog=pow_single_thermal.cog
crossbow _powerup thingflags=0x400 model3d=bowp.3do cog=pow_crossbow.cog
repeatergun _powerup thingflags=0x400 model3d=rptp.3do cog=pow_repeater.cog
railgun _powerup thingflags=0x400 model3d=rldp.3do cog=pow_railgun.cog respawn=60.000000
singleseqcharge _powerup thingflags=0x400 model3d=seqp_1.3do cog=pow_single_sequencer.cog
concrifle _powerup thingflags=0x400 model3d=conp.3do cog=pow_concrifle.cog respawn=60.000000
+fpbryarpistol bryarpistol collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+fpstrifle strifle collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+fpdetonator singledetonator collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+fpcrossbow crossbow collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+fprepeatergun repeatergun collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+fprailgun railgun collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+fpseqcharge singleseqcharge collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+fpconcrifle concrifle collide=0 timer=4.000000 typeflags=0x0 respawn=0.000000
+telesparks none orient=(0.000000/0.000000/0.000000) type=particle timer=0.120000 typeflags=0x3f material=00teleport.mat range=0.030000 rate=256.000000 maxthrust=80.000000 elementsize=0.002000 count=256
bubble none orient=(0.000000/0.000000/0.000000) type=cog move=physics thingflags=0x10000000 timer=3.000000 sprite=bubble.spr mass=0.050000 physflags=0x200 vel=(0.000000/0.000000/0.300000)
bubble2 bubble sprite=bubble2.spr vel=(0.000000/0.000000/0.450000)
bubble3 bubble sprite=bubble3.spr vel=(0.000000/0.000000/0.600000)
+watersplash none orient=(0.000000/0.000000/0.000000) type=explosion timer=0.500000 sprite=splash.spr typeflags=0x1 damageclass=0x4
+watersplash2 +watersplash sprite=splooshx.spr
+dstrifle _droppowerup thingflags=0x400 model3d=strp.3do cog=pow_dstrifle.cog height=0.035177
_limb none orient=(0.000000/0.000000/0.000000) type=corpse collide=1 move=physics thingflags=0x400 timer=30.000001 model3d=stlimb.3do size=0.102337 movesize=0.000001 cog=00_bloodtrail.cog surfdrag=1.000000 airdrag=4.000000 mass=15.000000 physflags=0x44261 buoyancy=0.500000
+rylimb _limb model3d=rylimb.3do size=0.050000 movesize=0.010000
+rhlimb _limb model3d=rhlimb.3do size=0.050000 movesize=0.010000
shrapnel_5 _debris model3d=shrp_5.3do size=0.084000 movesize=0.084000
+xtank1_exp _explosion thingflags=0x1 light=0.200000 timer=0.800000 sprite=detx.spr soundclass=exp_probe.snd typeflags=0x17 damage=90.000000 blasttime=0.700000 force=100.000000 maxlight=0.800000 range=0.450000 debris=shrapnel_1 debris=shrapnel_2 debris=shrapnel_3 debris=shrapnel_5
+xtank4_exp +xtank1_exp sprite=tiex.spr soundclass=exp_tie.snd damage=250.000000 force=300.000000 range=0.700000 debris=shrapnel_1 debris=shrapnel_2 debris=shrapnel_3 debris=shrapnel_5
+crane_exp +xtank4_exp damage=50.000000 force=75.000000 range=0.500000 debris=shrapnel_1 debris=shrapnel_2 debris=shrapnel_3 debris=shrapnel_5
+sentry_exp +grenade_exp damage=5.000000 force=50.000000
+crate_exp +sentry_exp damage=30.000000 force=75.000000 range=0.200000
+dhealthpack _droppowerup thingflags=0x408 model3d=hepk.3do cog=pow_health.cog height=0.023701
+dbactatank _droppowerup thingflags=0x400 model3d=bact.3do cog=pow_bacta.cog height=0.028885
+dshield _droppowerup thingflags=0x400 model3d=shld.3do cog=pow_shields.cog height=0.021618
+dbattery _droppowerup thingflags=0x408 model3d=battery.3do cog=pow_battery.cog height=0.022909
+denergycell _droppowerup thingflags=0x400 model3d=ecel.3do cog=pow_energy.cog height=0.022435
+dpowercell _droppowerup thingflags=0x400 model3d=pcel.3do cog=pow_power.cog height=0.017868
+dsmbp _droppowerup thingflags=0x400 model3d=bpck.3do cog=pow_smbkpk.cog height=0.036337
+rycw_punch +ry_punch damage=5.000000
reeyeescw reeyeesfist weapon=+rycw_punch typeflags=0x1020001
+gonk_exp +grenade_exp damage=20.000000
+dgreedopistol _droppowerup thingflags=0x400 model3d=ggun.3do cog=pow_bryar.cog height=0.011450
+scrate_exp +crate_exp damage=10.000000 force=25.000000 range=0.100000
+r2r5_exp +grenade_exp damage=10.000000 force=50.000000
+sparks none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=1.000000 mass=1.000000 physflags=0x201 typeflags=0x3d material=embers.mat range=0.030000 rate=32.000000 maxthrust=20.000000 elementsize=0.010000 count=32
+limb_blood none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.250000 physflags=0x201 vel=(0.000000/0.000000/0.200000) typeflags=0x27 material=00gsmoke.mat range=0.020000 rate=48.000000 maxthrust=3.000000 elementsize=0.005000 count=16
end
################################
If you look at this and other level jkls' template sections, you'll notice that most of the templates are the same. This is because most of the objects that are created in levels are weapons, projectiles, powerups, standard actors, etc - these things will be in all of the original levels and most custom ones.
All templates have a name, a base template, and a list of arguments. A template's name is what cogs will use to refer to it in their symbols section. Some names have an underscore before them to signify that they're just base templates. JK doesn't care if there's an underscore there or not, it's more of a comment. The plus sign before some of the names usually means that the template is a projectile, explosion, or particle cloud. Like the underscore, it's more comment than syntax.
After the template's name comes their base (or parent) template. All of the parent template's properties will be given to the child template. But if the child template has a property that the parent also has, the child's property value will be used instead. Any other template can be a base template, but it must come before the template that uses it - you cannot use a parent template that comes after its child template in the list. If no parent template is needed, you can write none instead of a template name.
Next comes the list of arguments. These are all the properties that the template has specific values for (in some cases there are default values for properties not defined). Remember that child templates will inherit properties they don't have defined from their parents (parent templates may have a parent of their own). The most important property for us is cog. This property tells JK that the template has a cog assigned to it. This cog should come from the cogscripts list.
From a cog, you will be able to retrieve the value of and change most of these properties once there is an actual thing created from the template. You cannot change a template from cog, only the thing created from it. Let's say you want to place a stormtrooper in your level. Although just about everybody uses a level editor to do this, you can do it manually by adding an entry to the things section in your .jkl file. This entry will consist of the template name and a position to create the thing at.
Now let's assume that the template's cog is storm.cog. As soon as the level loads and your stormtrooper is created storm.cog will begin receiveing events from its stormtrooper. Because this is a class cog, every stormtrooper in the level will be sending events to this one cog. The first event storm.cog will receive is created. This tells the cog that your stormtrooper has been created in the level.
Inventory
On this page, we'll go over a brief outline of the player's inventory. Here's the items.dat file from resource\res2\misc.
# Item definition file for Jedi Knight
# ========================================================================================
# name id min max flags args
# ========================================================================================
###########
# Weapons #
###########
# ========================================================================================
none 0 0 0 0x004
fists 1 0 1 0x024 cog=weap_fists.cog
bryar_pistol 2 0 1 0x0a4 cog=weap_bryar.cog
stormtrooper_rifle 3 0 1 0x0a4 cog=weap_strifle.cog
thermal_detonator 4 0 30 0x0a4 cog=weap_thermdet.cog
tusken_prod 5 0 1 0x0a4 cog=weap_crossbow.cog
repeater 6 0 1 0x0a4 cog=weap_repeater.cog
rail_detonator 7 0 1 0x0a4 cog=weap_raildet.cog
sequencer_charge 8 0 30 0x0a4 cog=weap_seqcharge.cog
concussion_rifle 9 0 1 0x0a4 cog=weap_concrifle.cog
lightsaber 10 0 1 0x0a4 cog=weap_saber.cog
# ========================================================================================
###################
# Ammo and Energy #
###################
# ========================================================================================
#energy is used for bryar pistol and stormtrooper rifle.
energy 11 0 500 0x080
#power is used for the the bowcaster, repeater and concussion rifle.
power 12 0 500 0x080
#battery is used for other inventory items.
battery 13 0 200 0x020
#force is used for the force powers.
forcemana 14 0 400 0x000
#rail charges
railcharges 15 0 30 0x080
# ========================================================================================
###########
# Bonuses #
###########
#new force stars gained in a level.
new_stars 16 0 32 0x000
#spendable stars
spend_stars 17 0 32 0x000
#the choice
choice 18 0 2 0x000
#############################
# Damage multiplier powerup #
#############################
# ========================================================================================
# Bin 19 is reserved !!!
# Damage multiplier powerup should come before force powers...
# ========================================================================================
##############
#Force Powers#
##############
# Note that the icon names are taken from these names:
# ========================================================================================
# Attributes
jedi_rank 20 0 8.0 0x000 cog=force_well.cog
# ........................................................................................
# Basic Powers
f_jump 21 0 4.0 0x108 cog=force_jump.cog
f_speed 22 0 4.0 0x108 cog=force_speed.cog
f_seeing 23 0 4.0 0x108 cog=force_seeing.cog
f_pull 24 0 4.0 0x108 cog=force_pull.cog
# ........................................................................................
# Light Side Powers
f_healing 25 0 4.0 0x108 cog=force_heal.cog
f_persuasion 26 0 4.0 0x108 cog=force_persuasion.cog
f_blinding 27 0 4.0 0x108 cog=force_blinding.cog
f_absorb 28 0 4.0 0x118 cog=force_absorb.cog
# ........................................................................................
# Light Side Bonus Powers
f_protection 29 0 4.0 0x118 cog=force_protection.cog
# ........................................................................................
# Dark Side Powers
f_throw 30 0 4.0 0x108 cog=force_throw.cog
f_grip 31 0 4.0 0x108 cog=force_grip.cog
f_lightning 32 0 4.0 0x108 cog=force_lightning.cog
f_destruction 33 0 4.0 0x108 cog=force_destruction.cog
# ........................................................................................
# Dark Side Bonus Powers
f_deadlysight 34 0 4.0 0x108 cog=force_deadlysight.cog
# ========================================================================================
#################
#Inventory Items#
#################
# Note that the icon names are taken from these names:
# ========================================================================================
bactatank 40 0 5 0x102 cog=item_bacta.cog
irgoggles 41 0 1 0x102 cog=item_irgoggles.cog
fieldlight 42 1 1 0x122 cog=item_fieldlight.cog
keyimperial 43 0 1 0x042 cog=item_keyimperial.cog
wrench 44 0 1 0x042 cog=item_wrench.cog
datadisk 45 0 1 0x042 cog=item_datadisk.cog
keyred 46 0 1 0x042 cog=item_keyred.cog
keyblue 47 0 1 0x042 cog=item_keyblue.cog
keyyellow 48 0 1 0x042 cog=item_keyyellow.cog
wrchblue 49 0 1 0x042 cog=item_wrenchblue.cog
wrchyellow 50 0 1 0x042 cog=item_wrenchyellow.cog
keygreen 51 0 1 0x042 cog=item_keygreen.cog
# ========================================================================================
#####################
# Player Statistics #
#####################
# ========================================================================================
shields 60 0 200.0 0x030 cog=item_shields.cog
force_armor 61 0 200.0 0x000
supershields 62 0 1.0 0x010 #cog=item_supershields.cog
powerboost 63 1.0 2.0 0x000
s_dark 64 0 1.0 0x000
s_light 65 0 1.0 0x000
revive 66 0 1.0 0x000
# ========================================================================================
###########
# Scoring #
###########
# ========================================================================================
secrets 70 0 20 0x000
maxsecrets 71 0 20 0x000
# morality
peds_killed 72 0 1000 0x000
peds_total 73 0 1000 0x000
force_morality 74 -40 40 0x000
alignment 75 -100 100 0x000
# ========================================================================================
#####################
# Multiplayer Modes #
#####################
# ========================================================================================
teamcolor 80 0 2 0x040
redflag 81 0 1 0x048
goldflag 82 0 1 0x048
redkey 83 0 1 0x042 cog=ctf_itemkeyred.cog
goldkey 84 0 1 0x042 cog=ctf_itemkeygold.cog
# ========================================================================================
############################
# Goals & Level Completion #
############################
# ========================================================================================
# Bins 99 - 115 are RESERVED
# ========================================================================================
# They will store the number of the first goal description text in cogStrings.uni, and the
# display status of up to 16 goals (0 to 15).
# ========================================================================================
stringOffset 99 0 99999 0x000
goal00 100 0 1000 0x040
goal01 101 0 1000 0x040
goal02 102 0 1000 0x040
goal03 103 0 1000 0x040
goal04 104 0 1000 0x040
goal05 105 0 1000 0x040
goal06 106 0 1000 0x040
goal07 107 0 1000 0x040
goal08 108 0 1000 0x040
goal09 109 0 1000 0x040
goal10 110 0 1000 0x040
goal11 111 0 1000 0x040
goal12 112 0 1000 0x040
goal13 113 0 1000 0x040
goal14 114 0 1000 0x040
goal15 115 0 1000 0x040
hotkeyOffset 150 0 99999 0x000
# =============== #
# MAX Bins = 199 #
# =============== #
end
LucasArts was nice enough to leave a lot of commenting in this file for us. All of the lines beginning with a pound sign are comments - JK will ignore them when it parses the file.
As outlined at the top, bins have a name, an ID, a minimum value, a maximum value, flags, and arguments. The name is pretty obvious, and the only time you'll need to worry about this is when you're naming icons (*.bm) for the forces and items - JK generates a name from the bin name and looks for the icon under that name.
The bin's ID is what you will use to access that bin from your code. When we get to the actual Cog commands later on, you'll see how you'll use bin numbers.
The minimum value is the smallest number you can assign to a bin. The main reason to have a "bin" is to hold something - in this case a value. And so it follows that the maximum value is the highest number you can assign to a bin.
A flag is a number used to store true or false settings. We'll cover flags in depth later on. For now, just remember that this flag tells JK what the bin is supposed to do - whether it's supposed to be for a weapon, item, force power, or just a hotkey.
An argument is a term used in programming to mean a value assigned to something. A parameter (which it's often confused with) is an allotted place for an argument. The only known argument that you can add to an inventory bin is its cog assignment. You can see that some of the bins have a cog=x.cog after them. The assigned cog will be able to receive events from that inventory bin.
Resources
Gob Files
Gob files are containers that hold JK's resources. Gob files contain a directory system just like windows' folders. You will need a special program to open gobs and display their directories and files. When JK is searching for resources, it will look in both the gob directories and the windows' folders. For example, if JK is looking for example.cog in the resource directory, it will look for it in both resource\cog and resource\res2.gob\cog. You can take files out of the gob file and put them in their respective windows folders and JK will find them just the same.
Resource Priorities
When JK is loading resources, it will look for them in several locations. When it finds a file with a matching name, it will stop there and load that file. So the order in which it searches directories is important to us.
There are four directories that JK will search for the subfolders containing resources. In order of priority they are: the install dir of JK, the folder given with the path switch, the episode folder, and then the resource folder.
The installation dir of JK is the folder containing jk.exe. It does not normally contain resource subfolders (such as cog, mat, etc), but if you add them, JK will look through them for every resource before going on to the path dir (if it's used). The path dir is only given to JK if the path switch is used. Just like with the install dir, JK will look for the resource subfolders in the path dir for every resource it loads before going to the episode or resource folders.
The episode folder contains all of JK's level files inside of gobs. Episode is different in that the resources must be inside the gob file or JK will not see them. JK does not search episode for all resources - only the ones loaded by the level's jkl. And if the level's jkl lists a resource that is not in the level's gob file, then JK will go to the resource dir.
Resource is the fourth place JK checks for resources listed in the level's jkl (including the jkl if it's not in episode), but the third place for resources listed in the items.dat and static.jkl - because JK doesn't check the level gob.
In the install dir, the path dir, and in resource, you can use gob files as well as actual windows folders. JK will search the windows directories before searching the gob files. So if you have a cog\weap_bryar.cog and a test.gob\cog\weap_bryar.cog both in JK's install directory, JK will choose the one outside the gob.
No-CD JK
The Jedi Knight CD has a file called jk_.cd which is in the gamedata\resource directory. By copying that file from the CD to your own resource folder on the hard drive, you can run JK without using a CD. You must have a complete installation for this to work. And if you want the movies as well, you can copy the video folder to your hard drive and JK will play them.
JED (a .jkl editing program) will ask you for a CD to make sure you really have JK, but all it wants is the first two smacker cutscenes - 01-02A.smk and 03-04A.smk. To fix that, crreate a gamedata\resource\video\ directory on one of your drives, put those two movies in it, and tell JED that's your CD drive. You can also use a mapped drive if you want. Another thing about the movies is that the first one gets really aggravating after a while - it's the opening cutscene. To skip that, just delete 01-02A.smk or rename it.
JK.exe
The real Jedi Knight program is jk.exe, you should never use the launcher. Just to save time, you should hide everything inside your JK install dir except for jk.exe, resource, and episode - you'll never have to use any of the other files.
CMD Switches
JK.exe accepts special program commands called switches. Create a shortcut to JK.exe and view its properties. In the Shortcut tab, you'll see a box called "target". This is the command that windows will run when you click the shortcut (picture a command prompt). After the original command that the shortcut has, you can add special commands for JK. The most important one for editing is the path command. To use it, write "-path folder" with no quotes after the shortcut command. This will make JK look for resources inside a folder named "folder" before it searches the other resource directories. This is how you can make JK load patches.
Review
Right now, you should understand how JK loads levels and the resources for them. You should understand how cogs are loaded into memory, and how cogs relate to levels, templates, and the inventory.
There are no code examples in this chapter because you should be familiar with what cog has to do before you try use it. Going straight to cog's syntax would be a mistake because you'd have nothing to base your understanding on.