about summary refs log tree commit diff
path: root/datasrc
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-06-12 10:51:48 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-06-12 10:51:48 +0000
commitf6c67c29cd10d41b877ee1319801edc01b625e72 (patch)
tree6ca26c44ac0218a57d078a6f72034f2924b44104 /datasrc
parent0d3b988c1aed8f6b91879a801253db81a251a532 (diff)
downloadzcatch-f6c67c29cd10d41b877ee1319801edc01b625e72.tar.gz
zcatch-f6c67c29cd10d41b877ee1319801edc01b625e72.zip
large commit with loads of clean up. more is comming
Diffstat (limited to 'datasrc')
-rw-r--r--datasrc/client.dts83
-rw-r--r--datasrc/compile.py287
-rw-r--r--datasrc/content.py808
-rw-r--r--datasrc/data.ds699
-rw-r--r--datasrc/datatypes.py205
-rw-r--r--datasrc/network.dts2
-rw-r--r--datasrc/network.py61
-rw-r--r--datasrc/server.dts25
-rw-r--r--datasrc/teewars.dsd24
9 files changed, 855 insertions, 1339 deletions
diff --git a/datasrc/client.dts b/datasrc/client.dts
deleted file mode 100644
index 93786646..00000000
--- a/datasrc/client.dts
+++ /dev/null
@@ -1,83 +0,0 @@
-struct image {
-	int id = 0
-	string filename = filename@1
-}
-
-struct spriteset {
-	ptr:image img = @1
-	int gridx = @2
-	int gridy = @3
-}
-
-struct sprite {
-	ptr:spriteset set = parent
-	int x = @1
-	int y = @2
-	int w = @3
-	int h = @4
-}
-
-struct sound {
-	int id = 0
-	string filename = @0
-}
-
-struct soundset {
-	int last = 0
-	array:sound sounds = *
-}
-
-struct spriteptr {
-	ptr:sprite psprite = @0
-}
-
-struct weapon {
-	ptr:sprite sprite_body = sprite_body@1
-	ptr:sprite sprite_cursor = sprite_cursor@1
-	ptr:sprite sprite_proj = sprite_proj@1
-	array:spriteptr sprite_muzzle = sprite_muzzles.*
-	
-	int nummuzzlesprites = nummuzzlesprites@1
-	int recoil = recoil@1
-	int visual_size = visual_size@1
-	int muzzleduration = muzzleduration@1
-	float offsetx = offsetx@1
-	float offsety = offsety@1
-	float muzzleoffsetx = muzzleoffsetx@1
-	float muzzleoffsety = muzzleoffsety@1
-}
-
-struct keyframe {
-	float time =  @0
-	float x = @1
-	float y = @2
-	float angle = @3
-}
-
-struct sequence {
-	array:keyframe frames = *
-}
-
-struct animation {
-	instance:sequence body = body
-	instance:sequence back_foot = back_foot
-	instance:sequence front_foot = front_foot
-	instance:sequence attach = attach
-}
-
-struct data_container {
-	array:image images = images.*
-	array:spriteset spritesets = sprites.*
-	array:sprite sprites = sprites.*.*
-	array:weapon weapons = weapons.*
-
-	array:soundset sounds = sounds.*
-	array:animation animations = animations.*
-}
-
-const array:int weapon = weapons.*
-const array:int sound = sounds.*
-const array:int image = images.*
-const array:int sprite = sprites.*.*
-const array:int anim = animations.*
-const array:int powerup = powerups.*
diff --git a/datasrc/compile.py b/datasrc/compile.py
index 5df84c23..38457e91 100644
--- a/datasrc/compile.py
+++ b/datasrc/compile.py
@@ -1,9 +1,8 @@
 import os, imp, sys
-import datatypes
+from datatypes import *
 import content
 import network
 
-	
 def create_enum_table(names, num):
 	lines = []
 	lines += ["enum", "{"]
@@ -13,180 +12,114 @@ def create_enum_table(names, num):
 	lines += ["\t%s" % num, "};"]
 	return lines
 	
-gen_content_header = False
-gen_content_source = True
-
-
-# collect sprites
-sprites = []
-for set in content.Sprites:
-	sprites += set.sprites
-
-
-if gen_content_header:
-	
-	print """
-struct SOUND
-{
-	int id;
-	const char *filename;
-};
-
-struct SOUNDSET
-{
-	int num_sounds;
-	SOUND *sound;
-};
-
-struct IMAGE
-{
-	int id;
-	const char *filename;
-};
-
-struct SPRITESET
-{
-	IMAGE *image;
-	int gridx;
-	int gridy;
-};
-
-struct SPRITE
-{
-	SPRITESET *set;
-	int x, y, w, h;
-};
-
-"""
-
-	def generate_struct(this, name, parent_name):
-		print "struct %s" % name
-
-		print "{"
-		if parent_name:
-			print "\t%s base;" % parent_name
-		for var in this.fields[this.baselen:]:
-			for l in var.emit_declaration(): print "\t"+l
-		print "};"
-
-	generate_struct(content.WeaponBase, "WEAPONSPEC", None)
-	for weapon in content.Weapons:
-		generate_struct(weapon, "WEAPONSPEC_%s"%weapon.name.upper(), "WEAPONSPEC")
-
-	# generate enums
-	for l in create_enum_table(["SOUND_"+o.name.upper() for o in content.Sounds], "NUM_SOUNDS"): print l
-	for l in create_enum_table(["IMAGE_"+o.name.upper() for o in content.Images], "NUM_IMAGES"): print l
-	for l in create_enum_table(["SPRITE_"+o.name.upper() for o in sprites], "NUM_SPRITES"): print l
-
-	for l in create_enum_table(["WEAPONTYPE_"+o.name.upper() for o in content.Weapons], "NUM_WEAPONTYPES"): print l
-
-if gen_content_source:
-	# generate data
-	for s in content.Sounds:
-		print "static SOUND sounds_%s[%d] = {" % (s.name, len(s.files))
-		for filename in s.files:
-			print '\t{%d, "%s"},' % (-1, filename)
-		print "};"
-		
-	print "static SOUNDSET soundsets[%d] = {" % len(content.Sounds)
-	for s in content.Sounds:
-		print "\t{%d, sounds_%s}," % (len(s.files), s.name)
-		#for filename in s.files:
-		#	print "\t{%d, '%s'}," % (-1, filename)
-	print "};"
-
-	print "static IMAGE images[%d] = {" % len(content.Images)
-	for i in content.Images:
-		print '\t{%d, "%s"},' % (-1, i.filename)
-	print "};"
-
-	print "static SPRITESET spritesets[%d] = {" % len(content.Sprites)
-	for set in content.Sprites:
-		if set.image:
-			print '\t{&images[IMAGE_%s], %d, %d},' % (set.image.upper(), set.grid[0], set.grid[1])
-		else:
-			print '\t{0, %d, %d},' % (set.grid[0], set.grid[1])
-	print "};"
-
-	print "static SPRITE sprites[%d] = {" % len(sprites)
-	spritesetid = 0
-	for set in content.Sprites:
-		for sprite in set.sprites:
-			print '\t{&spritesets[%d], %d, %d, %d, %d},' % (spritesetid, sprite.pos[0], sprite.pos[1], sprite.pos[2], sprite.pos[3])
-		spritesetid += 1
-	print "};"
-
-	for weapon in content.Weapons:
-		print "static WEAPONSPEC_%s weapon_%s = {" % (weapon.name.upper(), weapon.name)
-		for var in weapon.fields:
-			for l in var.emit_definition(): print "\t"+l,
-			print ","
-		print "};"
-
-	print "struct WEAPONS"
+def EmitEnum(names, num):
+	print "enum"
 	print "{"
-	print "\tWEAPONSPEC *id[%d];" % len(content.Weapons)
-	for w in content.Weapons:
-		print "\tWEAPONSPEC_%s &weapon_%s;" % (w.name.upper(), w.name)
-	print ""
-	print "};"
-
-	print "static WEAPONS weapons = {{%s}," % (",".join(["&weapon_%s.base"%w.name for w in content.Weapons]))
-	for w in content.Weapons:
-		print "\tweapon_%s," % w.name
+	print "\t%s=0,"%names[0]
+	for name in names[1:]:
+		print "\t%s,"%name
+	print "\t%s" % num
 	print "};"
+		
 
-
-	
-	print """
-struct DATACONTAINER
-{
-	int num_sounds;
-	SOUNDSET *sounds;
-
-	int num_images;
-	IMAGE *images;
+gen_network_header = False
+gen_network_source = False
+gen_client_content_header = False
+gen_client_content_source = False
+gen_server_content_header = False
+gen_server_content_source = False
+
+if "network_header" in sys.argv: gen_network_header = True
+if "network_source" in sys.argv: gen_network_source = True
+if "client_content_header" in sys.argv: gen_client_content_header = True
+if "client_content_source" in sys.argv: gen_client_content_source = True
+if "server_content_header" in sys.argv: gen_server_content_header = True
+if "server_content_source" in sys.argv: gen_server_content_source = True
+
+if gen_client_content_header or gen_server_content_header:
+	# emit the type declarations
+	contentlines = file("datasrc/content.py").readlines()
+	order = []
+	for line in contentlines:
+		line = line.strip()
+		if line[:6] == "class " and '(Struct)' in line:
+			order += [line.split()[1].split("(")[0]]
+	for name in order:
+		EmitTypeDeclaration(content.__dict__[name])
+		
+	# the container pointer
+	print 'extern DATACONTAINER *data;';
 	
-	int num_sprites;
-	SPRITE *sprites;
+	# enums
+	EmitEnum(["IMAGE_%s"%i.name.value.upper() for i in content.container.images.items], "NUM_IMAGES")
+	EmitEnum(["ANIM_%s"%i.name.value.upper() for i in content.container.animations.items], "NUM_ANIMS")
+	EmitEnum(["SPRITE_%s"%i.name.value.upper() for i in content.container.sprites.items], "NUM_SPRITES")
+
+if gen_client_content_source or gen_server_content_source:
+	if gen_client_content_source:
+		print '#include "gc_data.h"'
+	if gen_server_content_source:
+		print '#include "gs_data.h"'
+	EmitDefinition(content.container, "datacontainer")
+	print 'DATACONTAINER *data = &datacontainer;';
 
-	WEAPONS &weapons;
-};"""
-
-	print "DATACONTAINER data = {"
-	print "\t%d, soundsets," % len(content.Sounds)
-	print "\t%d, images," % len(content.Images)
-	print "\t%d, sprites," % len(content.Sprites)
-	print "\tweapons,"
-	print "};"
+# NETWORK
+if gen_network_header:
 	
+	print network.RawHeader
 	
-# NETWORK
-if 0:
-
-
 	for e in network.Enums:
 		for l in create_enum_table(["%s_%s"%(e.name, v) for v in e.values], "NUM_%sS"%e.name): print l
 		print ""
 		
-	for l in create_enum_table([o.enum_name for o in network.Objects], "NUM_NETOBJTYPES"): print l
+	for l in create_enum_table(["NETOBJ_INVALID"]+[o.enum_name for o in network.Objects], "NUM_NETOBJTYPES"): print l
 	print ""
-	for l in create_enum_table([o.enum_name for o in network.Messages], "NUM_NETMSGTYPES"): print l
+	for l in create_enum_table(["NETMSG_INVALID"]+[o.enum_name for o in network.Messages], "NUM_NETMSGTYPES"): print l
 	print ""
 		
 	for item in network.Objects + network.Messages:
 		for line in item.emit_declaration():
 			print line
 		print ""
+		
+	EmitEnum(["SOUND_%s"%i.name.value.upper() for i in content.container.sounds.items], "NUM_SOUNDS")
+	EmitEnum(["WEAPON_%s"%i.name.value.upper() for i in content.container.weapons.id.items], "NUM_WEAPONS")
+
+	print "int netobj_validate(int type, void *data, int size);"
+	print "const char *netobj_get_name(int type);"
+	print "void *netmsg_secure_unpack(int type);"
+	print "const char *netmsg_get_name(int type);"
+	print "const char *netmsg_failed_on();"
+	print "int netobj_num_corrections();"
+	print "const char *netobj_corrected_on();"
+	
 
-
-if 0:		
+if gen_network_source:
 	# create names
 	lines = []
+	
+	lines += ['#include <engine/e_common_interface.h>']
+	lines += ['#include "g_protocol.h"']
+
+	lines += ['const char *msg_failed_on = "";']
+	lines += ['const char *obj_corrected_on = "";']
+	lines += ['static int num_corrections = 0;']
+	lines += ['int netobj_num_corrections() { return num_corrections; }']
+	lines += ['const char *netobj_corrected_on() { return obj_corrected_on; }']
+	lines += ['const char *netmsg_failed_on() { return msg_failed_on; }']
+	lines += ['const int max_int = 0x7fffffff;']
+
+	lines += ['static int netobj_clamp_int(const char *error_msg, int v, int min, int max)']
+	lines += ['{']
+	lines += ['\tif(v<min) { obj_corrected_on = error_msg; num_corrections++; return min; }']
+	lines += ['\tif(v>max) { obj_corrected_on = error_msg; num_corrections++; return max; }']
+	lines += ['\treturn v;']
+	lines += ['}']
+
 	lines += ["static const char *netobj_names[] = {"]
 	lines += ['\t"%s",' % o.name for o in network.Objects]
 	lines += ['\t""', "};", ""]
-	
+
 	for l in lines:
 		print l
 
@@ -197,8 +130,10 @@ if 0:
 
 	# create validate tables
 	lines = []
+	lines += ['static int validate_invalid(void *data, int size) { return -1; }']
 	lines += ["typedef int(*VALIDATEFUNC)(void *data, int size);"]
 	lines += ["static VALIDATEFUNC validate_funcs[] = {"]
+	lines += ['\tvalidate_invalid,']
 	lines += ['\tvalidate_%s,' % o.name for o in network.Objects]
 	lines += ["\t0x0", "};", ""]
 
@@ -208,6 +143,54 @@ if 0:
 	lines += ["\treturn validate_funcs[type](data, size);"]
 	lines += ["};", ""]
 	
+	lines += ['const char *netobj_get_name(int type)']
+	lines += ['{']
+	lines += ['\tif(type < 0 || type >= NUM_NETOBJTYPES) return "(out of range)";']
+	lines += ['\treturn netobj_names[type];']
+	lines += ['};']
+	lines += ['']
+
+	for item in network.Messages:
+		for line in item.emit_unpack():
+			print line
+		print ""
+
+	lines += ['static void *secure_unpack_invalid() { return 0; }']
+	lines += ['typedef void *(*SECUREUNPACKFUNC)();']
+	lines += ['static SECUREUNPACKFUNC secure_unpack_funcs[] = {']
+	lines += ['\tsecure_unpack_invalid,']
+	for msg in network.Messages:
+		lines += ['\tsecure_unpack_%s,' % msg.name]
+	lines += ['\t0x0']
+	lines += ['};']
+	
+	#
+	lines += ['void *netmsg_secure_unpack(int type)']
+	lines += ['{']
+	lines += ['\tvoid *msg;']
+	lines += ['\tmsg_failed_on = "";']
+	lines += ['\tif(type < 0 || type >= NUM_NETMSGTYPES) return 0;']
+	lines += ['\tmsg = secure_unpack_funcs[type]();']
+	lines += ['\tif(msg_unpack_error()) return 0;']
+	lines += ['\treturn msg;']
+	lines += ['};']
+	lines += ['']
+
+	lines += ['static const char *message_names[] = {']
+	lines += ['\t"invalid",']
+	for msg in network.Messages:
+		lines += ['\t"%s",' % msg.name]
+	lines += ['\t""']
+	lines += ['};']
+	lines += ['']
+
+	lines += ['const char *netmsg_get_name(int type)']
+	lines += ['{']
+	lines += ['\tif(type < 0 || type >= NUM_NETMSGTYPES) return "(out of range)";']
+	lines += ['\treturn message_names[type];']
+	lines += ['};']
+	lines += ['']
+
 	for l in lines:
 		print l
 	
diff --git a/datasrc/content.py b/datasrc/content.py
index 6eb671a6..3a2bfe35 100644
--- a/datasrc/content.py
+++ b/datasrc/content.py
@@ -1,350 +1,476 @@
 import copy
-
-class SoundSet:
-	def __init__(self, name, files):
-		self.name = name
-		self.files = files
-
-class Image:
-	def __init__(self, name, filename):
-		self.name = name
-		self.filename = filename
-		
-class Pickup:
-	def __init__(self, name, respawntime=15, spawndelay=0):
-		self.name = name
-		self.respawntime = respawntime
-		self.spawndelay = spawndelay
-
-class Variable:
-	def __init__(self, name, value):
-		self.name = name
-		self.value = value
-
-class Int(Variable):
-	def emit_declaration(self):
-		return ["int %s;"%self.name]
-	def emit_definition(self):
-		return ["%d"%self.value]
-		
-class Float(Variable):
-	def emit_declaration(self):
-		return ["float %s;"%self.name]
-	def emit_definition(self):
-		return ["%ff"%self.value]
+from datatypes import *
+
+class Sound(Struct):
+	def __init__(self, filename=""):
+		Struct.__init__(self, "SOUND")
+		self.id = Int(0)
+		self.filename = String(filename)
+
+class SoundSet(Struct):
+	def __init__(self, name="", files=[]):
+		Struct.__init__(self, "SOUNDSET")
+		self.name = String(name)
+		self.sounds = Array(Sound())
+		self.last = Int(-1)
+		for name in files:
+			self.sounds.Add(Sound(name))
+
+class Image(Struct):
+	def __init__(self, name="", filename=""):
+		Struct.__init__(self, "IMAGE")
+		self.name = String(name)
+		self.filename = String(filename)
+		self.id = Int(-1)
 	
-class String(Variable):
-	def emit_declaration(self):
-		return ["const char *%s;"%self.name]
-	def emit_definition(self):
-		return ['"%s"'%self.value]
-		
-class SpriteRef(Variable):
-	def emit_declaration(self):
-		return ["SPRITE *%s;"%self.name]
-	def emit_definition(self):
-		return ['&sprites[SPRITE_%s]'%self.value.upper()]
-
-class SpriteSet:
-	def __init__(self, image, grid, sprites):
-		self.image = image
-		self.grid = grid
-		self.sprites = sprites
+class SpriteSet(Struct):
+	def __init__(self, name="", image=None, gridx=0, gridy=0):
+		Struct.__init__(self, "SPRITESET")
+		self.image = Pointer(Image, image) # TODO
+		self.gridx = Int(gridx)
+		self.gridy = Int(gridy)
+
+class Sprite(Struct):
+	def __init__(self, name="", Set=None, x=0, y=0, w=0, h=0):
+		Struct.__init__(self, "SPRITE")
+		self.name = String(name)
+		self.set = Pointer(SpriteSet, Set) # TODO
+		self.x = Int(x)
+		self.y = Int(y)
+		self.w = Int(w)
+		self.h = Int(h)
+
+class Pickup(Struct):
+	def __init__(self, name="", respawntime=20, spawndelay=0):
+		Struct.__init__(self, "PICKUPSPEC")
+		self.name = String(name)
+		self.respawntime = Int(respawntime)
+		self.spawndelay = Int(spawndelay)
+
+class AnimKeyframe(Struct):
+	def __init__(self, time=0, x=0, y=0, angle=0):
+		Struct.__init__(self, "ANIM_KEYFRAME")
+		self.time = Float(time)
+		self.x = Float(x)
+		self.y = Float(y)
+		self.angle = Float(angle)
+
+class AnimSequence(Struct):
+	def __init__(self):
+		Struct.__init__(self, "ANIM_SEQUENCE")
+		self.frames = Array(AnimKeyframe())
+
+class Animation(Struct):
+	def __init__(self, name=""):
+		Struct.__init__(self, "ANIMATION")
+		self.name = String(name)
+		self.body = AnimSequence()
+		self.back_foot = AnimSequence()
+		self.front_foot = AnimSequence()
+		self.attach = AnimSequence()
+
+class WeaponSpec(Struct):
+	def __init__(self, container=None, name=""):
+		Struct.__init__(self, "WEAPONSPEC")
+		self.name = String(name)
+		self.sprite_body = Pointer(Sprite, Sprite())
+		self.sprite_cursor = Pointer(Sprite, Sprite())
+		self.sprite_proj = Pointer(Sprite, Sprite())
+		self.sprite_muzzles = Array(Pointer(Sprite, Sprite()))
+		self.visual_size = Int(96)
 		
-class Sprite:
-	def __init__(self, name, pos):
-		self.name = name
-		self.pos = pos
-
-# TODO: rename this
-class FieldStorage:
-	def __init__(self, name, base, fields):
-		self.name = name
-		self.fields = []
-		if base:
-			self.fields = copy.deepcopy(base.fields)
-		self.base = base
-		self.baselen = len(self.fields)
+		self.firedelay = Int(500)
+		self.maxammo = Int(10)
+		self.ammoregentime = Int(0)
+		self.damage = Int(1)
+
+		self.offsetx = Float(0)
+		self.offsety = Float(0)
+		self.muzzleoffsetx = Float(0)
+		self.muzzleoffsety = Float(0)
+		self.muzzleduration = Float(5)
+
+		# dig out sprites if we have a container
+		if container:
+			for sprite in container.sprites.items:
+				if sprite.name.value == "weapon_"+name+"_body": self.sprite_body.Set(sprite)
+				elif sprite.name.value == "weapon_"+name+"_cursor": self.sprite_cursor.Set(sprite)
+				elif sprite.name.value == "weapon_"+name+"_proj": self.sprite_proj.Set(sprite)
+				elif "weapon_"+name+"_muzzle" in sprite.name.value:
+					self.sprite_muzzles.Add(Pointer(Sprite, sprite))
+
+class Weapon_Hammer(Struct):
+	def __init__(self):
+		Struct.__init__(self, "WEAPONSPEC_HAMMER")
+		self.base = Pointer(WeaponSpec, WeaponSpec())
+
+class Weapon_Gun(Struct):
+	def __init__(self):
+		Struct.__init__(self, "WEAPONSPEC_GUN")
+		self.base = Pointer(WeaponSpec, WeaponSpec())
+		self.curvature = Float(1.25)
+		self.speed = Float(2200)
+		self.lifetime = Float(2.0)
 		
-		self.autoupdate()
+class Weapon_Shotgun(Struct):
+	def __init__(self):
+		Struct.__init__(self, "WEAPONSPEC_SHOTGUN")
+		self.base = Pointer(WeaponSpec, WeaponSpec())
+		self.curvature = Float(1.25)
+		self.speed = Float(2200)
+		self.speeddiff = Float(0.8)
+		self.lifetime = Float(0.25)		
+
+class Weapon_Grenade(Struct):
+	def __init__(self):
+		Struct.__init__(self, "WEAPONSPEC_GRENADE")
+		self.base = Pointer(WeaponSpec, WeaponSpec())
+		self.curvature = Float(7.0)
+		self.speed = Float(1000)
+		self.lifetime = Float(2.0)
+
+class Weapon_Rifle(Struct):
+	def __init__(self):
+		Struct.__init__(self, "WEAPONSPEC_RIFLE")
+		self.base = Pointer(WeaponSpec, WeaponSpec())
+		self.reach = Float(800.0)
+		self.bounce_delay = Int(150)
+		self.bounce_num = Int(1)
+		self.bounce_cost = Float(0)
 		
-		self.update_all(fields)
-	
-	def update_all(self, fields):
-		for v in fields:
-			if not self.update(v):
-				self.fields += [v]
-	
-	def update(self, value):
-		for i in xrange(0, len(self.fields)):
-			if self.fields[i].name == value.name:
-				self.fields[i] = value
-				return True
-		return False
-	
-	def autoupdate(self):
-		pass
+class Weapon_Ninja(Struct):
+	def __init__(self):
+		Struct.__init__(self, "WEAPONSPEC_NINJA")
+		self.base = Pointer(WeaponSpec, WeaponSpec())
+		self.duration = Int(15000)
+		self.movetime = Int(200)
+		self.velocity = Int(50)
+
+class Weapons(Struct):
+	def __init__(self):
+		Struct.__init__(self, "WEAPONSPECS")
+		self.hammer = Weapon_Hammer()
+		self.gun = Weapon_Hammer()
+		self.shotgun = Weapon_Shotgun()
+		self.grenade = Weapon_Grenade()
+		self.rifle = Weapon_Rifle()
+		self.ninja = Weapon_Ninja()
+		self.id = Array(WeaponSpec())
+
+class DataContainer(Struct):
+	def __init__(self):
+		Struct.__init__(self, "DATACONTAINER")
+		self.sounds = Array(SoundSet())
+		self.images = Array(Image())
+		self.pickups = Array(Pickup())
+		self.spritesets = Array(SpriteSet())
+		self.sprites = Array(Sprite())
+		self.animations = Array(Animation())
+		self.weapons = Weapons()
 
 def FileList(format, num):
-	return [format%x for x in xrange(1,num)]
+	return [format%(x+1) for x in xrange(0,num)]
+
+container = DataContainer()
+container.sounds.Add(SoundSet("gun_fire", FileList("data/audio/wp_gun_fire-%02d.wv", 3)))
+container.sounds.Add(SoundSet("shotgun_fire", FileList("data/audio/wp_shotty_fire-%02d.wv", 3)))
+
+container.sounds.Add(SoundSet("grenade_fire", FileList("data/audio/wp_flump_launch-%02d.wv", 3)))
+container.sounds.Add(SoundSet("hammer_fire", FileList("data/audio/wp_hammer_swing-%02d.wv", 3)))
+container.sounds.Add(SoundSet("hammer_hit", FileList("data/audio/wp_hammer_hit-%02d.wv", 3)))
+container.sounds.Add(SoundSet("ninja_fire", FileList("data/audio/wp_ninja_attack-%02d.wv", 3)))
+container.sounds.Add(SoundSet("grenade_explode", FileList("data/audio/wp_flump_explo-%02d.wv", 3)))
+container.sounds.Add(SoundSet("ninja_hit", FileList("data/audio/wp_ninja_hit-%02d.wv", 3)))
+container.sounds.Add(SoundSet("rifle_fire", FileList("data/audio/wp_rifle_fire-%02d.wv", 3)))
+container.sounds.Add(SoundSet("rifle_bounce", FileList("data/audio/wp_rifle_bnce-%02d.wv", 3)))
+container.sounds.Add(SoundSet("weapon_switch", FileList("data/audio/wp_switch-%02d.wv", 3)))
+
+container.sounds.Add(SoundSet("player_pain_short", FileList("data/audio/vo_teefault_pain_short-%02d.wv", 12)))
+container.sounds.Add(SoundSet("player_pain_long", FileList("data/audio/vo_teefault_pain_long-%02d.wv", 2)))
+
+container.sounds.Add(SoundSet("body_land", FileList("data/audio/foley_land-%02d.wv", 4)))
+container.sounds.Add(SoundSet("player_airjump", FileList("data/audio/foley_dbljump-%02d.wv", 3)))
+container.sounds.Add(SoundSet("player_jump", FileList("data/audio/foley_foot_left-%02d.wv", 4) +  FileList("data/audio/foley_foot_right-%02d.wv", 4)))
+container.sounds.Add(SoundSet("player_die", FileList("data/audio/foley_body_splat-%02d.wv", 3)))
+container.sounds.Add(SoundSet("player_spawn", FileList("data/audio/vo_teefault_spawn-%02d.wv", 7)))
+container.sounds.Add(SoundSet("player_skid", FileList("data/audio/sfx_skid-%02d.wv", 4)))
+container.sounds.Add(SoundSet("tee_cry", FileList("data/audio/vo_teefault_cry-%02d.wv", 2)))
+
+container.sounds.Add(SoundSet("hook_loop", FileList("data/audio/hook_loop-%02d.wv", 2)))
+
+container.sounds.Add(SoundSet("hook_attach_ground", FileList("data/audio/hook_attach-%02d.wv", 3)))
+container.sounds.Add(SoundSet("hook_attach_player", FileList("data/audio/foley_body_impact-%02d.wv", 3)))
+container.sounds.Add(SoundSet("pickup_health", FileList("data/audio/sfx_pickup_hrt-%02d.wv", 2)))
+container.sounds.Add(SoundSet("pickup_armor", FileList("data/audio/sfx_pickup_arm-%02d.wv", 4)))
+
+container.sounds.Add(SoundSet("pickup_grenade", FileList("data/audio/sfx_pickup_arm-%02d.wv", 1)))
+container.sounds.Add(SoundSet("pickup_shotgun", FileList("data/audio/sfx_pickup_arm-%02d.wv", 1)))
+container.sounds.Add(SoundSet("pickup_ninja", FileList("data/audio/sfx_pickup_arm-%02d.wv", 1)))
+container.sounds.Add(SoundSet("weapon_spawn", FileList("data/audio/sfx_spawn_wpn-%02d.wv", 3)))
+container.sounds.Add(SoundSet("weapon_noammo", FileList("data/audio/wp_noammo-%02d.wv", 5)))
+
+container.sounds.Add(SoundSet("hit", FileList("data/audio/sfx_hit_weak-%02d.wv", 2)))
+
+container.sounds.Add(SoundSet("chat_server", ["data/audio/sfx_msg-server.wv"]))
+container.sounds.Add(SoundSet("chat_client", ["data/audio/sfx_msg-client.wv"]))
+container.sounds.Add(SoundSet("ctf_drop", ["data/audio/sfx_ctf_drop.wv"]))
+container.sounds.Add(SoundSet("ctf_return", ["data/audio/sfx_ctf_rtn.wv"]))
+container.sounds.Add(SoundSet("ctf_grab_pl", ["data/audio/sfx_ctf_grab_pl.wv"]))
+container.sounds.Add(SoundSet("ctf_grab_en", ["data/audio/sfx_ctf_grab_en.wv"]))
+container.sounds.Add(SoundSet("ctf_capture", ["data/audio/sfx_ctf_cap_pl.wv"]))
+
+image_null = Image("null", "")
+image_particles = Image("particles", "data/particles.png")
+image_game = Image("game", "data/game.png")
+image_browseicons = Image("browseicons", "data/browse_icons.png")
+image_emoticons = Image("emoticons", "data/emoticons.png")
+
+container.images.Add(image_null)
+container.images.Add(image_game)
+container.images.Add(image_particles)
+container.images.Add(Image("cursor", "data/gui_cursor.png"))
+container.images.Add(Image("banner", "data/gui_logo.png"))
+container.images.Add(image_emoticons)
+container.images.Add(image_browseicons)
+container.images.Add(Image("console_bg", "data/console.png"))
+container.images.Add(Image("console_bar", "data/console_bar.png"))
+
+container.pickups.Add(Pickup("health"))
+container.pickups.Add(Pickup("armor"))
+container.pickups.Add(Pickup("weapon"))
+container.pickups.Add(Pickup("ninja", 90, 90))
+
+set_particles = SpriteSet("particles", image_particles, 8, 8)
+set_game = SpriteSet("game", image_game, 32, 16)
+set_tee = SpriteSet("tee", image_null, 8, 4)
+set_browseicons = SpriteSet("browseicons", image_browseicons, 4, 1)
+set_emoticons = SpriteSet("emoticons", image_emoticons, 4, 4)
+
+container.spritesets.Add(set_particles)
+container.spritesets.Add(set_game)
+container.spritesets.Add(set_tee)
+container.spritesets.Add(set_browseicons)
+container.spritesets.Add(set_emoticons)
+
+container.sprites.Add(Sprite("part_slice", set_particles, 0,0,1,1))
+container.sprites.Add(Sprite("part_ball", set_particles, 1,0,1,1))
+container.sprites.Add(Sprite("part_splat01", set_particles, 2,0,1,1))
+container.sprites.Add(Sprite("part_splat02", set_particles, 3,0,1,1))
+container.sprites.Add(Sprite("part_splat03", set_particles, 4,0,1,1))
+
+container.sprites.Add(Sprite("part_smoke", set_particles, 0,1,1,1))
+container.sprites.Add(Sprite("part_shell", set_particles, 0,2,2,2))
+container.sprites.Add(Sprite("part_expl01", set_particles, 0,4,4,4))
+container.sprites.Add(Sprite("part_airjump", set_particles, 2,2,2,2))
+
+container.sprites.Add(Sprite("health_full", set_game, 21,0,2,2))
+container.sprites.Add(Sprite("health_empty", set_game, 23,0,2,2))
+container.sprites.Add(Sprite("armor_full", set_game, 21,2,2,2))
+container.sprites.Add(Sprite("armor_empty", set_game, 23,2,2,2))
+
+container.sprites.Add(Sprite("star1", set_game, 15,0,2,2))
+container.sprites.Add(Sprite("star2", set_game, 17,0,2,2))
+container.sprites.Add(Sprite("star3", set_game, 19,0,2,2))
 	
-
-Sounds = [
-	SoundSet("gun_fire", FileList("data/audio/wp_gun_fire-%02d.wv", 3)),
-	SoundSet("shotgun_fire", FileList("data/audio/wp_shotty_fire-%02d.wv", 3)),
-	SoundSet("grenade_fire", FileList("data/audio/wp_flump_launch-%02d.wv", 3)),
-	SoundSet("hammer_fire", FileList("data/audio/wp_hammer_swing-%02d.wv", 3)),
-	SoundSet("hammer_hit", FileList("data/audio/wp_hammer_hit-%02d.wv", 3)),
-	SoundSet("ninja_fire", FileList("data/audio/wp_ninja_attack-%02d.wv", 3)),
-	SoundSet("grenade_explode", FileList("data/audio/wp_flump_explo-%02d.wv", 3)),
-	SoundSet("ninja_hit", FileList("data/audio/wp_ninja_hit-%02d.wv", 3)),
-	SoundSet("rifle_fire", FileList("data/audio/wp_rifle_fire-%02d.wv", 3)),
-	SoundSet("rifle_bounce", FileList("data/audio/wp_rifle_bnce-%02d.wv", 3)),
-	SoundSet("weapon_switch", FileList("data/audio/wp_switch-%02d.wv", 3)),
-
-	SoundSet("player_pain_short", FileList("data/audio/vo_teefault_pain_short-%02d.wv", 12)),
-	SoundSet("player_pain_long", FileList("data/audio/vo_teefault_pain_long-%02d.wv", 2)),
-
-	SoundSet("body_land", FileList("data/audio/foley_land-%02d.wv", 4)),
-	SoundSet("player_airjump", FileList("data/audio/foley_dbljump-%02d.wv", 3)),
-	SoundSet("player_jump", FileList("data/audio/foley_foot_left-%02d.wv", 4) +  FileList("data/audio/foley_foot_right-%02d.wv", 4)),
-	SoundSet("player_die", FileList("data/audio/foley_body_splat-%02d.wv", 3)),
-	SoundSet("player_spawn", FileList("data/audio/vo_teefault_spawn-%02d.wv", 7)),
-	SoundSet("player_skid", FileList("data/audio/sfx_skid-%02d.wv", 4)),
-	SoundSet("tee_cry", FileList("data/audio/vo_teefault_cry-%02d.wv", 2)),
-
-	SoundSet("hook_loop", FileList("data/audio/hook_loop-%02d.wv", 2)),
-
-	SoundSet("hook_attach_ground", FileList("data/audio/hook_attach-%02d.wv", 3)),
-	SoundSet("hook_attach_player", FileList("data/audio/foley_body_impact-%02d.wv", 3)),
-	SoundSet("pickup_health", FileList("data/audio/sfx_pickup_hrt-%02d.wv", 2)),
-	SoundSet("pickup_armor", FileList("data/audio/sfx_pickup_arm-%02d.wv", 4)),
-
-	SoundSet("pickup_grenade", FileList("data/audio/sfx_pickup_arm-%02d.wv", 1)),
-	SoundSet("pickup_shotgun", FileList("data/audio/sfx_pickup_arm-%02d.wv", 1)),
-	SoundSet("pickup_ninja", FileList("data/audio/sfx_pickup_arm-%02d.wv", 1)),
-	SoundSet("weapon_spawn", FileList("data/audio/sfx_spawn_wpn-%02d.wv", 3)),
-	SoundSet("weapon_noammo", FileList("data/audio/wp_noammo-%02d.wv", 5)),
-
-	SoundSet("hit", FileList("data/audio/sfx_hit_weak-%02d.wv", 2)),
-
-	SoundSet("chat_server", ["data/audio/sfx_msg-server.wv"]),
-	SoundSet("chat_client", ["data/audio/sfx_msg-client.wv"]),
-	SoundSet("ctf_drop", ["data/audio/sfx_ctf_drop.wv"]),
-	SoundSet("ctf_return", ["data/audio/sfx_ctf_rtn.wv"]),
-	SoundSet("ctf_grab_pl", ["data/audio/sfx_ctf_grab_pl.wv"]),
-	SoundSet("ctf_grab_en", ["data/audio/sfx_ctf_grab_en.wv"]),
-	SoundSet("ctf_capture", ["data/audio/sfx_ctf_cap_pl.wv"]),
-]
-
-Images = [
-	Image("null", ""),
-	Image("game", "data/game.png"),
-	Image("particles", "data/particles.png"),
-	Image("cursor", "data/gui_cursor.png"),
-	Image("banner", "data/gui_logo.png"),
-	Image("emoticons", "data/emoticons.png"),
-	Image("browseicons", "data/browse_icons.png"),
-	Image("console_bg", "data/console.png"),
-	Image("console_bar", "data/console_bar.png"),
-]
-
-Pickups = [
-	Pickup("health"),
-	Pickup("armor"),
-	Pickup("weapon"),
-	Pickup("ninja", 90, 90),
-]
-
-Sprites = [
-	SpriteSet("particles", (8,8), [
-		Sprite("part_slice", (0,0,1,1)),
-		Sprite("part_ball", (1,0,1,1)),
-		Sprite("part_splat01", (2,0,1,1)),
-		Sprite("part_splat02", (3,0,1,1)),
-		Sprite("part_splat03", (4,0,1,1)),
-
-		Sprite("part_smoke", (0,1,1,1)),
-		Sprite("part_shell", (0,2,2,2)),
-		Sprite("part_expl01", (0,4,4,4)),
-		Sprite("part_airjump", (2,2,2,2)),
-	]),
-
-	SpriteSet("game", (8,8), [
-		Sprite("health_full", (21,0,2,2)),
-		Sprite("health_empty", (23,0,2,2)),
-		Sprite("armor_full", (21,2,2,2)),
-		Sprite("armor_empty", (23,2,2,2)),
-		
-		Sprite("star1", (15,0,2,2)),
-		Sprite("star2", (17,0,2,2)),
-		Sprite("star3", (19,0,2,2)),
+container.sprites.Add(Sprite("part1", set_game, 6,0,1,1))
+container.sprites.Add(Sprite("part2", set_game, 6,1,1,1))
+container.sprites.Add(Sprite("part3", set_game, 7,0,1,1))
+container.sprites.Add(Sprite("part4", set_game, 7,1,1,1))
+container.sprites.Add(Sprite("part5", set_game, 8,0,1,1))
+container.sprites.Add(Sprite("part6", set_game, 8,1,1,1))
+container.sprites.Add(Sprite("part7", set_game, 9,0,2,2))
+container.sprites.Add(Sprite("part8", set_game, 11,0,2,2))
+container.sprites.Add(Sprite("part9", set_game, 13,0,2,2))
+
+container.sprites.Add(Sprite("weapon_gun_body", set_game, 2,4,4,2))
+container.sprites.Add(Sprite("weapon_gun_cursor", set_game, 0,4,2,2))
+container.sprites.Add(Sprite("weapon_gun_proj", set_game, 6,4,2,2))
+container.sprites.Add(Sprite("weapon_gun_muzzle1", set_game, 8,4,3,2))
+container.sprites.Add(Sprite("weapon_gun_muzzle2", set_game, 12,4,3,2))
+container.sprites.Add(Sprite("weapon_gun_muzzle3", set_game, 16,4,3,2))
+
+container.sprites.Add(Sprite("weapon_shotgun_body", set_game, 2,6,8,2))
+container.sprites.Add(Sprite("weapon_shotgun_cursor", set_game, 0,6,2,2))
+container.sprites.Add(Sprite("weapon_shotgun_proj", set_game, 10,6,2,2))
+container.sprites.Add(Sprite("weapon_shotgun_muzzle1", set_game, 12,6,3,2))
+container.sprites.Add(Sprite("weapon_shotgun_muzzle2", set_game, 16,6,3,2))
+container.sprites.Add(Sprite("weapon_shotgun_muzzle3", set_game, 20,6,3,2))
+
+container.sprites.Add(Sprite("weapon_grenade_body", set_game, 2,8,7,2))
+container.sprites.Add(Sprite("weapon_grenade_cursor", set_game, 0,8,2,2))
+container.sprites.Add(Sprite("weapon_grenade_proj", set_game, 10,8,2,2))
+
+container.sprites.Add(Sprite("weapon_hammer_body", set_game, 2,1,4,3))
+container.sprites.Add(Sprite("weapon_hammer_cursor", set_game, 0,0,2,2))
+container.sprites.Add(Sprite("weapon_hammer_proj", set_game, 0,0,0,0))
+
+container.sprites.Add(Sprite("weapon_ninja_body", set_game, 2,10,7,2))
+container.sprites.Add(Sprite("weapon_ninja_cursor", set_game, 0,10,2,2))
+container.sprites.Add(Sprite("weapon_ninja_proj", set_game, 0,0,0,0))
+
+container.sprites.Add(Sprite("weapon_rifle_body", set_game, 2,12,7,3))
+container.sprites.Add(Sprite("weapon_rifle_cursor", set_game, 0,12,2,2))
+container.sprites.Add(Sprite("weapon_rifle_proj", set_game, 10,12,2,2))
+
+container.sprites.Add(Sprite("hook_chain", set_game, 2,0,1,1))
+container.sprites.Add(Sprite("hook_head", set_game, 3,0,2,1))
+
+container.sprites.Add(Sprite("hadoken1", set_game, 25,0,7,4))
+container.sprites.Add(Sprite("hadoken2", set_game, 25,4,7,4))
+container.sprites.Add(Sprite("hadoken3", set_game, 25,8,7,4))
+
+container.sprites.Add(Sprite("pickup_health", set_game, 10,2,2,2))
+container.sprites.Add(Sprite("pickup_armor", set_game, 12,2,2,2))
+container.sprites.Add(Sprite("pickup_weapon", set_game, 3,0,6,2))
+container.sprites.Add(Sprite("pickup_ninja", set_game, 3,10,7,2))
+
+container.sprites.Add(Sprite("flag_blue", set_game, 12,8,4,8))
+container.sprites.Add(Sprite("flag_red", set_game, 16,8,4,8))
+
+container.sprites.Add(Sprite("tee_body", set_tee, 0,0,3,3))
+container.sprites.Add(Sprite("tee_body_outline", set_tee, 3,0,3,3))
+container.sprites.Add(Sprite("tee_foot", set_tee, 6,1,2,1))
+container.sprites.Add(Sprite("tee_foot_outline", set_tee, 6,2,2,1))
+container.sprites.Add(Sprite("tee_hand", set_tee, 6,0,1,1))
+container.sprites.Add(Sprite("tee_hand_outline", set_tee, 7,0,1,1))
+container.sprites.Add(Sprite("tee_eye_normal", set_tee, 2,3,1,1))
+container.sprites.Add(Sprite("tee_eye_angry", set_tee, 3,3,1,1))
+container.sprites.Add(Sprite("tee_eye_pain", set_tee, 4,3,1,1))
+container.sprites.Add(Sprite("tee_eye_happy", set_tee, 5,3,1,1))
+container.sprites.Add(Sprite("tee_eye_dead", set_tee, 6,3,1,1))
+container.sprites.Add(Sprite("tee_eye_surprise", set_tee, 7,3,1,1))
+
+container.sprites.Add(Sprite("oop", set_emoticons, 0, 0, 1, 1))
+container.sprites.Add(Sprite("exclamation", set_emoticons, 1, 0, 1, 1))
+container.sprites.Add(Sprite("hearts", set_emoticons, 2, 0, 1, 1))
+container.sprites.Add(Sprite("drop", set_emoticons, 3, 0, 1, 1))
+container.sprites.Add(Sprite("dotdot", set_emoticons, 0, 1, 1, 1))
+container.sprites.Add(Sprite("music1", set_emoticons, 1, 1, 1, 1))
+container.sprites.Add(Sprite("music2", set_emoticons, 2, 1, 1, 1))
+container.sprites.Add(Sprite("ghost", set_emoticons, 3, 1, 1, 1))
+container.sprites.Add(Sprite("sushi", set_emoticons, 0, 2, 1, 1))
+container.sprites.Add(Sprite("splattee", set_emoticons, 1, 2, 1, 1))
+container.sprites.Add(Sprite("deviltee", set_emoticons, 2, 2, 1, 1))
+container.sprites.Add(Sprite("zomg", set_emoticons, 3, 2, 1, 1))
+container.sprites.Add(Sprite("zzz", set_emoticons, 0, 3, 1, 1))
+container.sprites.Add(Sprite("blank1", set_emoticons, 1, 3, 1, 1))
+container.sprites.Add(Sprite("deadtee", set_emoticons, 2, 3, 1, 1))
+container.sprites.Add(Sprite("blank2", set_emoticons, 3, 3, 1, 1))
+
+
+container.sprites.Add(Sprite("browse_lock", set_browseicons, 0,0,1,1))
+container.sprites.Add(Sprite("browse_progress1", set_browseicons, 1,0,1,1))
+container.sprites.Add(Sprite("browse_progress2", set_browseicons, 2,0,1,1))
+container.sprites.Add(Sprite("browse_progress3", set_browseicons, 3,0,1,1))
+
+anim = Animation("base")
+anim.body.frames.Add(AnimKeyframe(0, 0, -4, 0))
+anim.back_foot.frames.Add(AnimKeyframe(0, 0, 10, 0))
+anim.front_foot.frames.Add(AnimKeyframe(0, 0, 10, 0))
+container.animations.Add(anim)
+
+anim = Animation("idle")
+anim.back_foot.frames.Add(AnimKeyframe(0, -7, 0, 0))
+anim.front_foot.frames.Add(AnimKeyframe(0, 7, 0, 0))
+container.animations.Add(anim)
+
+anim = Animation("inair")
+anim.back_foot.frames.Add(AnimKeyframe(0, -3, 0, -0.1))
+anim.front_foot.frames.Add(AnimKeyframe(0, 3, 0, -0.1))
+container.animations.Add(anim)
+
+anim = Animation("walk")
+anim.body.frames.Add(AnimKeyframe(0.0, 0, 0, 0))
+anim.body.frames.Add(AnimKeyframe(0.2, 0,-1, 0))
+anim.body.frames.Add(AnimKeyframe(0.4, 0, 0, 0))
+anim.body.frames.Add(AnimKeyframe(0.6, 0, 0, 0))
+anim.body.frames.Add(AnimKeyframe(0.8, 0,-1, 0))
+anim.body.frames.Add(AnimKeyframe(1.0, 0, 0, 0))
+
+anim.back_foot.frames.Add(AnimKeyframe(0.0,  8, 0, 0))
+anim.back_foot.frames.Add(AnimKeyframe(0.2, -8, 0, 0))
+anim.back_foot.frames.Add(AnimKeyframe(0.4,-10,-4, 0.2))
+anim.back_foot.frames.Add(AnimKeyframe(0.6, -8,-8, 0.3))
+anim.back_foot.frames.Add(AnimKeyframe(0.8,  4,-4,-0.2))
+anim.back_foot.frames.Add(AnimKeyframe(1.0,  8, 0, 0))
+
+anim.front_foot.frames.Add(AnimKeyframe(0.0,-10,-4, 0.2))
+anim.front_foot.frames.Add(AnimKeyframe(0.2, -8,-8, 0.3))
+anim.front_foot.frames.Add(AnimKeyframe(0.4,  4,-4,-0.2))
+anim.front_foot.frames.Add(AnimKeyframe(0.6,  8, 0, 0))
+anim.front_foot.frames.Add(AnimKeyframe(0.8,  8, 0, 0))
+anim.front_foot.frames.Add(AnimKeyframe(1.0,-10, 0, 0.2))
+container.animations.Add(anim)
+
+anim = Animation("hammer_swing")
+anim.attach.frames.Add(AnimKeyframe(0.0, 0, 0, -0.10))
+anim.attach.frames.Add(AnimKeyframe(0.3, 0, 0,  0.25))
+anim.attach.frames.Add(AnimKeyframe(0.4, 0, 0,  0.30))
+anim.attach.frames.Add(AnimKeyframe(0.5, 0, 0,  0.25))
+anim.attach.frames.Add(AnimKeyframe(1.0, 0, 0, -0.10))
+container.animations.Add(anim)
 			
-		Sprite("part1", (6,0,1,1)),
-		Sprite("part2", (6,1,1,1)),
-		Sprite("part3", (7,0,1,1)),
-		Sprite("part4", (7,1,1,1)),
-		Sprite("part5", (8,0,1,1)),
-		Sprite("part6", (8,1,1,1)),
-		Sprite("part7", (9,0,2,2)),
-		Sprite("part8", (11,0,2,2)),
-		Sprite("part9", (13,0,2,2)),
-	
-		Sprite("weapon_gun_body", (2,4,4,2)),
-		Sprite("weapon_gun_cursor", (0,4,2,2)),
-		Sprite("weapon_gun_proj", (6,4,2,2)),
-		Sprite("weapon_gun_muzzle1", (8,4,3,2)),
-		Sprite("weapon_gun_muzzle2", (12,4,3,2)),
-		Sprite("weapon_gun_muzzle3", (16,4,3,2)),
-		
-		Sprite("weapon_shotgun_body", (2,6,8,2)),
-		Sprite("weapon_shotgun_cursor", (0,6,2,2)),
-		Sprite("weapon_shotgun_proj", (10,6,2,2)),
-		Sprite("weapon_shotgun_muzzle1", (12,6,3,2)),
-		Sprite("weapon_shotgun_muzzle2", (16,6,3,2)),
-		Sprite("weapon_shotgun_muzzle3", (20,6,3,2)),
-		
-		Sprite("weapon_grenade_body", (2,8,7,2)),
-		Sprite("weapon_grenade_cursor", (0,8,2,2)),
-		Sprite("weapon_grenade_proj", (10,8,2,2)),
-
-		Sprite("weapon_hammer_body", (2,1,4,3)),
-		Sprite("weapon_hammer_cursor", (0,0,2,2)),
-		Sprite("weapon_hammer_proj", (0,0,0,0)),
-		
-		Sprite("weapon_ninja_body", (2,10,7,2)),
-		Sprite("weapon_ninja_cursor", (0,10,2,2)),
-		Sprite("weapon_ninja_proj", (0,0,0,0)),
-
-		Sprite("weapon_rifle_body", (2,12,7,3)),
-		Sprite("weapon_rifle_cursor", (0,12,2,2)),
-		Sprite("weapon_rifle_proj", (10,12,2,2)),
-		
-		Sprite("hook_chain", (2,0,1,1)),
-		Sprite("hook_head", (3,0,2,1)),
-		
-		Sprite("hadoken1", (25,0,7,4)),
-		Sprite("hadoken2", (25,4,7,4)),
-		Sprite("hadoken3", (25,8,7,4)),
-		
-		Sprite("pickup_health", (10,2,2,2)),
-		Sprite("pickup_armor", (12,2,2,2)),
-		Sprite("pickup_weapon", (3,0,6,2)),
-		Sprite("pickup_ninja", (3,10,7,2)),
-
-		Sprite("flag_blue", (12,8,4,8)),
-		Sprite("flag_red", (16,8,4,8)),
-	]),
-	
-	SpriteSet(None, (8,4), [
-		Sprite("tee_body", (0,0,3,3)),
-		Sprite("tee_body_outline", (3,0,3,3)),
-		Sprite("tee_foot", (6,1,2,1)),
-		Sprite("tee_foot_outline", (6,2,2,1)),
-		Sprite("tee_hand", (6,0,1,1)),
-		Sprite("tee_hand_outline", (7,0,1,1)),
-		
-		Sprite("tee_eye_normal", (2,3,1,1)),
-		Sprite("tee_eye_angry", (3,3,1,1)),
-		Sprite("tee_eye_pain", (4,3,1,1)),
-		Sprite("tee_eye_happy", (5,3,1,1)),
-		Sprite("tee_eye_dead", (6,3,1,1)),
-		Sprite("tee_eye_surprise", (7,3,1,1)),
-	]),
-
-	SpriteSet("browseicons", (4,1), [
-		Sprite("browse_lock", (0,0,1,1)),
-		Sprite("browse_progress1", (1,0,1,1)),
-		Sprite("browse_progress2", (2,0,1,1)),
-		Sprite("browse_progress3", (3,0,1,1)),
-	]),
-]
-
-class Weapon(FieldStorage):
-	def autoupdate(self):
-		self.update(String("name", self.name))
-		self.update(SpriteRef("sprite_body", "weapon_%s_body"%self.name))
-		self.update(SpriteRef("sprite_cursor", "weapon_%s_cursor"%self.name))
-		self.update(SpriteRef("sprite_proj", "weapon_%s_proj"%self.name))
-
-WeaponBase = Weapon("weapon", None, [
-	String("name", "base"),
-	SpriteRef("sprite_body", None),
-	SpriteRef("sprite_cursor", None),
-	SpriteRef("sprite_proj", None),
-	Int("damage", 1),
-	Int("firedelay", 500),
-	Int("visual_size", 96),
-])
-
-Weapons = [
-	Weapon("hammer", WeaponBase, [
-		Int("firedelay", 100),
-		Int("damage", 3),
-	]),
-
-	Weapon("gun", WeaponBase, [
-		Int("firedelay", 100),
-		Int("damage", 1),
-
-		Float("curvature", 1.25),
-		Float("speed", 2200.0),
-		Float("lifetime", 2.0),
-	]),
-
-	Weapon("shotgun", WeaponBase, [
-		Int("firedelay", 500),
-		Int("damage", 1),
-
-		Float("curvature", 1.25),
-		Float("speed", 2200.0),
-		Float("speeddiff", 0.8),
-		Float("lifetime", 0.25),
-	]),
-
-	Weapon("grenade", WeaponBase, [
-		Int("firedelay", 100),
-		Int("damage", 6),
-
-		Float("curvature", 7.0),
-		Float("speed", 1000.0),
-		Float("lifetime", 2.0),
-	]),
-
-	Weapon("rifle", WeaponBase, [
-		Int("firedelay", 800),
-		Int("visual_size", 92),
-		Int("damage", 5),
-		
-		Float("reach", 800.0),
-		Float("bounce_delay", 150),
-		Float("bounce_num", 1),
-		Float("bounce_cost", 0),
-	]),
-	
-	Weapon("ninja", WeaponBase, [
-		Int("firedelay", 800),
-		Int("damage", 9),
-	]),	
-]
-
-ticks_per_second = 50.0
-Physics = FieldStorage("physics", None, [
-	Float("ground_control_speed", 10.0),
-	Float("ground_control_accel", 100.0 / ticks_per_second),
-	Float("ground_friction", 0.5),
-	Float("ground_jump_impulse", 12.6),
-	Float("air_jump_impulse", 11.5),
-	Float("air_control_speed", 250.0 / ticks_per_second),
-	Float("air_control_accel", 1.5),
-	Float("air_friction", 0.95),
-	Float("hook_length", 380.0),
-	Float("hook_fire_speed", 80.0),
-	Float("hook_drag_accel", 3.0),
-	Float("hook_drag_speed", 15.0),
-	Float("gravity", 0.5),
-
-	Float("velramp_start", 550),
-	Float("velramp_range", 2000),
-	Float("velramp_curvature", 1.4),
-])
+anim = Animation("ninja_swing")
+anim.attach.frames.Add(AnimKeyframe(0.00, 0, 0, -0.25))
+anim.attach.frames.Add(AnimKeyframe(0.10, 0, 0, -0.05))
+anim.attach.frames.Add(AnimKeyframe(0.15, 0, 0,  0.35))
+anim.attach.frames.Add(AnimKeyframe(0.42, 0, 0,  0.40))
+anim.attach.frames.Add(AnimKeyframe(0.50, 0, 0,  0.35))
+anim.attach.frames.Add(AnimKeyframe(1.00, 0, 0, -0.25))
+container.animations.Add(anim)
+
+weapon = WeaponSpec(container, "hammer")
+weapon.firedelay.Set(100)
+weapon.damage.Set(3)
+weapon.visual_size.Set(96)
+weapon.offsetx.Set(4)
+weapon.offsety.Set(-20)
+container.weapons.hammer.base.Set(weapon)
+container.weapons.id.Add(weapon)
+
+weapon = WeaponSpec(container, "gun")
+weapon.firedelay.Set(100)
+weapon.ammoregentime.Set(500)
+weapon.visual_size.Set(64)
+weapon.offsetx.Set(32)
+weapon.offsety.Set(-4)
+weapon.muzzleoffsetx.Set(50)
+weapon.muzzleoffsety.Set(6)
+container.weapons.gun.base.Set(weapon)
+container.weapons.id.Add(weapon)
+
+weapon = WeaponSpec(container, "shotgun")
+weapon.firedelay.Set(500)
+weapon.visual_size.Set(96)
+weapon.offsetx.Set(24)
+weapon.offsety.Set(-2)
+weapon.muzzleoffsetx.Set(70)
+weapon.muzzleoffsety.Set(6)
+container.weapons.shotgun.base.Set(weapon)
+container.weapons.id.Add(weapon)
+
+weapon = WeaponSpec(container, "grenade")
+weapon.firedelay.Set(500) # TODO: fix this
+weapon.visual_size.Set(96)
+weapon.offsetx.Set(24)
+weapon.offsety.Set(-2)
+container.weapons.grenade.base.Set(weapon)
+container.weapons.id.Add(weapon)
+
+weapon = WeaponSpec(container, "rifle")
+weapon.firedelay.Set(800)
+weapon.visual_size.Set(92)
+weapon.damage.Set(5)
+weapon.offsetx.Set(24)
+weapon.offsety.Set(-2)
+container.weapons.rifle.base.Set(weapon)
+container.weapons.id.Add(weapon)
+
+weapon = WeaponSpec(container, "ninja")
+weapon.firedelay.Set(800)
+weapon.damage.Set(9)
+weapon.visual_size.Set(96)
+weapon.offsetx.Set(0)
+weapon.offsety.Set(0)
+container.weapons.ninja.base.Set(weapon)
+container.weapons.id.Add(weapon)
diff --git a/datasrc/data.ds b/datasrc/data.ds
deleted file mode 100644
index 897a440e..00000000
--- a/datasrc/data.ds
+++ /dev/null
@@ -1,699 +0,0 @@
-sounds {
-	gun_fire {
-		"data/audio/wp_gun_fire-01.wv"
-		"data/audio/wp_gun_fire-02.wv"
-		"data/audio/wp_gun_fire-03.wv"
-	}
-
-	shotgun_fire {
-		"data/audio/wp_shotty_fire-01.wv"
-		"data/audio/wp_shotty_fire-02.wv"
-		"data/audio/wp_shotty_fire-03.wv"
-	}
-	
-	grenade_fire {
-		"data/audio/wp_flump_launch-01.wv"
-		"data/audio/wp_flump_launch-02.wv"
-		"data/audio/wp_flump_launch-03.wv"
-	}
-	
-	hammer_fire {
-		"data/audio/wp_hammer_swing-01.wv"
-		"data/audio/wp_hammer_swing-02.wv"
-		"data/audio/wp_hammer_swing-03.wv"
-	}
-
-	hammer_hit {
-		"data/audio/wp_hammer_hit-01.wv"
-		"data/audio/wp_hammer_hit-02.wv"
-		"data/audio/wp_hammer_hit-03.wv"
-	}
-	
-	ninja_fire { 
-		"data/audio/wp_ninja_attack-01.wv"
-		"data/audio/wp_ninja_attack-02.wv"
-		"data/audio/wp_ninja_attack-03.wv"
-	}
-
-	grenade_explode {
-		"data/audio/wp_flump_explo-01.wv"
-		"data/audio/wp_flump_explo-02.wv"
-		"data/audio/wp_flump_explo-03.wv"
-	}
-	
-	ninja_hit {
-		"data/audio/wp_ninja_hit-01.wv"
-		"data/audio/wp_ninja_hit-02.wv"
-		"data/audio/wp_ninja_hit-03.wv"
-	}
-	
-	rifle_fire {
-		"data/audio/wp_rifle_fire-01.wv"
-		"data/audio/wp_rifle_fire-02.wv"
-		"data/audio/wp_rifle_fire-03.wv"
-	}
-
-	rifle_bounce {
-		"data/audio/wp_rifle_bnce-01.wv"
-		"data/audio/wp_rifle_bnce-02.wv"
-		"data/audio/wp_rifle_bnce-03.wv"
-	}
-
-	weapon_switch { 
-		"data/audio/wp_switch-01.wv"
-		"data/audio/wp_switch-02.wv"
-		"data/audio/wp_switch-03.wv"
-	}
-
-	player_pain_short {
-		"data/audio/vo_teefault_pain_short-01.wv"
-		"data/audio/vo_teefault_pain_short-02.wv"
-		"data/audio/vo_teefault_pain_short-03.wv"
-		"data/audio/vo_teefault_pain_short-04.wv"
-		"data/audio/vo_teefault_pain_short-05.wv"
-		"data/audio/vo_teefault_pain_short-06.wv"
-		"data/audio/vo_teefault_pain_short-07.wv"
-		"data/audio/vo_teefault_pain_short-08.wv"
-		"data/audio/vo_teefault_pain_short-09.wv"
-		"data/audio/vo_teefault_pain_short-10.wv"
-		"data/audio/vo_teefault_pain_short-11.wv"
-		"data/audio/vo_teefault_pain_short-12.wv"
-	}
-
-	player_pain_long {
-		"data/audio/vo_teefault_pain_long-01.wv"
-		"data/audio/vo_teefault_pain_long-02.wv"
-	}
-
-	body_land {
-		"data/audio/foley_land-01.wv"
-		"data/audio/foley_land-02.wv"
-		"data/audio/foley_land-03.wv"
-		"data/audio/foley_land-04.wv"
-	}
-	
-	player_airjump {
-		"data/audio/foley_dbljump-01.wv"
-		"data/audio/foley_dbljump-02.wv"
-		"data/audio/foley_dbljump-03.wv"
-	}
-
-	player_jump {
-		"data/audio/foley_foot_left-01.wv"
-		"data/audio/foley_foot_left-02.wv"
-		"data/audio/foley_foot_left-03.wv"
-		"data/audio/foley_foot_left-04.wv"
-		"data/audio/foley_foot_right-01.wv"
-		"data/audio/foley_foot_right-02.wv"
-		"data/audio/foley_foot_right-03.wv"
-		"data/audio/foley_foot_right-04.wv"
-	}
-
-	player_die {
-		"data/audio/foley_body_splat-02.wv"
-		"data/audio/foley_body_splat-03.wv"
-		"data/audio/foley_body_splat-04.wv"
-	}
-	
-	player_spawn {
-		"data/audio/vo_teefault_spawn-01.wv"
-		"data/audio/vo_teefault_spawn-02.wv"
-		"data/audio/vo_teefault_spawn-03.wv"
-		"data/audio/vo_teefault_spawn-04.wv"
-		"data/audio/vo_teefault_spawn-05.wv"
-		"data/audio/vo_teefault_spawn-06.wv"
-		"data/audio/vo_teefault_spawn-07.wv"
-	}
-	
-	player_skid {
-		"data/audio/sfx_skid-01.wv"
-		"data/audio/sfx_skid-02.wv"
-		"data/audio/sfx_skid-03.wv"
-		"data/audio/sfx_skid-04.wv"
-	}
-
-	tee_cry {
-		"data/audio/vo_teefault_cry-01.wv"
-		"data/audio/vo_teefault_cry-02.wv"
-	}
-
-	hook_loop { 
-		"data/audio/hook_loop-01.wv"
-		"data/audio/hook_loop-02.wv"
-	}
-	
-	hook_attach_ground {
-		"data/audio/hook_attach-01.wv"
-		"data/audio/hook_attach-02.wv"
-		"data/audio/hook_attach-03.wv"
-	}
-	
-	hook_attach_player {
-		"data/audio/foley_body_impact-01.wv"
-		"data/audio/foley_body_impact-02.wv"
-		"data/audio/foley_body_impact-03.wv"
-	}
-		
-	pickup_health {
-		"data/audio/sfx_pickup_hrt-01.wv"
-		"data/audio/sfx_pickup_hrt-02.wv"
-	}
-	
-	pickup_armor {
-		"data/audio/sfx_pickup_arm-01.wv"
-		"data/audio/sfx_pickup_arm-02.wv"
-		"data/audio/sfx_pickup_arm-03.wv"
-		"data/audio/sfx_pickup_arm-04.wv"
-	}
-	
-	pickup_grenade {
-		"data/audio/sfx_pickup_launcher.wv"
-	}
-	
-	pickup_shotgun {
-		"data/audio/sfx_pickup_sg.wv"
-	}
-	
-	pickup_ninja {
-		"data/audio/sfx_pickup_ninja.wv"
-	}
-		
-	weapon_spawn {
-		"data/audio/sfx_spawn_wpn-01.wv"
-		"data/audio/sfx_spawn_wpn-02.wv"
-		"data/audio/sfx_spawn_wpn-03.wv"
-	}
-
-	weapon_noammo {
-		"data/audio/wp_noammo-01.wv"
-		"data/audio/wp_noammo-02.wv"
-		"data/audio/wp_noammo-03.wv"
-		"data/audio/wp_noammo-04.wv"
-		"data/audio/wp_noammo-05.wv"
-	}
-
-	hit {
-		"data/audio/sfx_hit_weak-01.wv"
-		"data/audio/sfx_hit_weak-02.wv"
-	}
-
-	chat_server {
-		"data/audio/sfx_msg-server.wv"
-	}
-	
-	chat_client {
-		"data/audio/sfx_msg-client.wv"
-	}
-
-	ctf_drop {
-		"data/audio/sfx_ctf_drop.wv"
-	}
-
-	ctf_return {
-		"data/audio/sfx_ctf_rtn.wv"
-	}
-	
-	ctf_grab_pl {
-		"data/audio/sfx_ctf_grab_pl.wv"
-	}
-
-	ctf_grab_en {
-		"data/audio/sfx_ctf_grab_en.wv"
-	}
-
-	ctf_capture {
-		"data/audio/sfx_ctf_cap_pl.wv"
-	}
-}
-
-
-images {
-	null {
-		filename ""
-	}
-
-	game {
-		filename "data/game.png"
-	}
-
-	particles {
-		filename "data/particles.png"
-	}
-
-	cursor {
-		filename "data/gui_cursor.png"
-	}
-
-	banner {
-		filename "data/gui_logo.png"
-	}
-
-	emoticons {
-		filename "data/emoticons.png"
-	}
-	
-	browseicons {
-		filename "data/browse_icons.png"
-	}
-
-	console_bg {
-		filename "data/console.png"
-	}
-	console_bar {
-		filename "data/console_bar.png"
-	}
-}
-
-powerups {
-	health {
-		amount 1
-		respawntime 15
-		startspawntime 0
-	}
-	armor {
-		amount 1
-		respawntime 15
-		startspawntime 0
-	}
-	weapon {
-		amount 10
-		respawntime 15
-		startspawntime 0
-	}
-	ninja {
-		amount 1
-		respawntime 90
-		startspawntime 90
-	}
-}
-
-weapons {
-	hammer {
-		sprite_body sprites.game.weapon_hammer_body
-		sprite_cursor sprites.game.weapon_hammer_cursor
-		sprite_proj sprites.game.weapon_hammer_proj
-		sprite_muzzles {
-		}
-		
-		nummuzzlesprites 0
-		muzzleoffsetx 0.0
-		muzzleoffsety 0.0
-		maxammo 10
-		recoil 10
-		firedelay 150
-		muzzleduration 0
-		visual_size 96
-		offsetx 4.0
-		offsety -20.0
-		meleedamage 4
-		meleereach 40
-		ammoregentime 0
-		duration -1
-		movetime 0
-		velocity 0
-	}
-	
-	gun {
-		sprite_body sprites.game.weapon_gun_body
-		sprite_cursor sprites.game.weapon_gun_cursor
-		sprite_proj sprites.game.weapon_gun_proj
-		sprite_muzzles {
-			sprites.game.weapon_gun_muzzle1
-			sprites.game.weapon_gun_muzzle2
-			sprites.game.weapon_gun_muzzle3
-		}
-
-		nummuzzlesprites 3
-		muzzleoffsetx 50.0
-		muzzleoffsety 6.0
-		maxammo 10
-		recoil 10
-		firedelay 100
-		muzzleduration 5
-		visual_size 64
-		offsetx 32.0
-		offsety 4.0
-		meleedamage 0
-		meleereach 0
-		ammoregentime 500
-		duration -1
-		movetime 0
-		velocity 0
-	}
-	
-	shotgun {
-		sprite_body sprites.game.weapon_shotgun_body
-		sprite_cursor sprites.game.weapon_shotgun_cursor
-		sprite_proj sprites.game.weapon_shotgun_proj
-		sprite_muzzles {
-			sprites.game.weapon_shotgun_muzzle1
-			sprites.game.weapon_shotgun_muzzle2
-			sprites.game.weapon_shotgun_muzzle3
-		}
-		
-		nummuzzlesprites 3
-		muzzleoffsetx 70.0
-		muzzleoffsety 6.0
-		maxammo 10
-		recoil 10
-		firedelay 500
-		muzzleduration 5
-		visual_size 96
-		offsetx 24.0
-		offsety -2.0
-		meleedamage 0
-		meleereach 0
-		ammoregentime 0
-		duration -1
-		movetime 0
-		velocity 0
-	}
-
-	grenade {
-		sprite_body sprites.game.weapon_grenade_body
-		sprite_cursor sprites.game.weapon_grenade_cursor
-		sprite_proj sprites.game.weapon_grenade_proj
-		sprite_muzzles {
-		}
-		
-		nummuzzlesprites 0
-		muzzleoffsetx 0.0
-		muzzleoffsety 0.0
-		maxammo 10
-		recoil 10
-		firedelay 600
-		muzzleduration 0
-		visual_size 96
-		offsetx 24.0
-		offsety -2.0
-		meleedamage 0
-		meleereach 0
-		ammoregentime 0
-		duration -1
-		movetime 0
-		velocity 0
-	}
-		
-	rifle {
-		sprite_body sprites.game.weapon_rifle_body
-		sprite_cursor sprites.game.weapon_rifle_cursor
-		sprite_proj sprites.game.weapon_rifle_proj
-		sprite_muzzles {
-		}
-		
-		nummuzzlesprites 3
-		muzzleoffsetx 0.0
-		muzzleoffsety 0.0
-		maxammo 10
-		recoil 10
-		firedelay 800
-		muzzleduration 0
-		visual_size 92
-		offsetx 24.0
-		offsety -2.0
-		meleedamage 0
-		meleereach 0
-		ammoregentime 0
-		duration -1
-		movetime 0
-		velocity 0
-	}
-
-	ninja {
-		sprite_body sprites.game.weapon_ninja_body
-		sprite_cursor sprites.game.weapon_ninja_cursor
-		sprite_proj sprites.game.weapon_ninja_proj
-		sprite_muzzles {
-			sprites.game.hadoken1
-			sprites.game.hadoken2
-			sprites.game.hadoken3
-		}
-		
-		nummuzzlesprites 3
-		muzzleoffsetx 40.0
-		muzzleoffsety -4.0
-		maxammo 0
-		recoil 0
-		firedelay 800
-		muzzleduration 0
-		visual_size 96
-		offsetx 0.0
-		offsety 0.0
-		meleedamage 9
-		meleereach 0
-		ammoregentime 0
-		duration 15000
-		movetime 200
-		velocity 50
-	}
-		
-}
-	
-sprites {
-
-	particles images.particles 8 8 {
-		part_slice 0 0 1 1
-		part_ball 1 0 1 1
-		part_splat01 2 0 1 1
-		part_splat02 3 0 1 1
-		part_splat03 4 0 1 1
-
-		part_smoke 0 1 1 1
-		part_shell 0 2 2 2
-		part_expl01 0 4 4 4
-		part_airjump 2 2 2 2
-	}
-
-	game images.game 32 16 {
-	
-		health_full 21 0 2 2
-		health_empty 23 0 2 2
-		armor_full 21 2 2 2
-		armor_empty 23 2 2 2
-		
-		star1 15 0 2 2
-		star2 17 0 2 2
-		star3 19 0 2 2
-			
-		part1 6 0 1 1
-		part2 6 1 1 1
-		part3 7 0 1 1
-		part4 7 1 1 1
-		part5 8 0 1 1
-		part6 8 1 1 1
-		part7 9 0 2 2
-		part8 11 0 2 2
-		part9 13 0 2 2
-	
-		weapon_gun_body 2 4 4 2
-		weapon_gun_cursor 0 4 2 2
-		weapon_gun_proj 6 4 2 2
-		weapon_gun_muzzle1 8 4 3 2
-		weapon_gun_muzzle2 12 4 3 2
-		weapon_gun_muzzle3 16 4 3 2
-		
-		weapon_shotgun_body 2 6 8 2
-		weapon_shotgun_cursor 0 6 2 2
-		weapon_shotgun_proj 10 6 2 2
-		weapon_shotgun_muzzle1 12 6 3 2
-		weapon_shotgun_muzzle2 16 6 3 2
-		weapon_shotgun_muzzle3 20 6 3 2
-		
-		weapon_grenade_body 2 8 7 2
-		weapon_grenade_cursor 0 8 2 2
-		weapon_grenade_proj 10 8 2 2
-
-		weapon_hammer_body 2 1 4 3
-		weapon_hammer_cursor 0 0 2 2
-		weapon_hammer_proj 0 0 0 0
-		
-		weapon_ninja_body 2 10 7 2
-		weapon_ninja_cursor 0 10 2 2
-		weapon_ninja_proj 0 0 0 0
-
-		weapon_rifle_body 2 12 7 3
-		weapon_rifle_cursor 0 12 2 2
-		weapon_rifle_proj 10 12 2 2
-		
-		hook_chain 2 0 1 1
-		hook_head 3 0 2 1
-		
-		hadoken1 25 0 7 4
-		hadoken2 25 4 7 4
-		hadoken3 25 8 7 4
-		
-		powerup_health 10 2 2 2
-		powerup_armor 12 2 2 2
-		powerup_weapon 3 0 6 2
-		powerup_ninja 3 10 7 2
-		powerup_timefield 3 0 6 2
-
-		flag_blue 12 8 4 8
-		flag_red 16 8 4 8
-
-	}
-	
-	tees images.null 8 4 {
-		tee_body 0 0 3 3
-		tee_body_outline 3 0 3 3
-		tee_foot 6 1 2 1
-		tee_foot_outline 6 2 2 1
-		tee_hand 6 0 1 1
-		tee_hand_outline 7 0 1 1
-		
-		tee_eye_normal 2 3 1 1
-		tee_eye_angry 3 3 1 1
-		tee_eye_pain 4 3 1 1
-		tee_eye_happy 5 3 1 1
-		tee_eye_dead 6 3 1 1
-		tee_eye_surprise 7 3 1 1
-	}
-
-	emoticons images.emoticons 4 4 {
-		oop 0 0 1 1
-		exclamation 1 0 1 1
-		hearts 2 0 1 1
-		drop 3 0 1 1
-		dotdot 0 1 1 1
-		music1 1 1 1 1
-		music2 2 1 1 1
-		ghost 3 1 1 1
-		sushi 0 2 1 1
-		splattee 1 2 1 1
-		deviltee 2 2 1 1
-		zomg 3 2 1 1
-		zzz 0 3 1 1
-		blank1 1 3 1 1
-		deadtee 2 3 1 1
-		blank2 3 3 1 1
-	}
-	
-	browseicons images.browseicons 4 1 {
-		browse_lock 0 0 1 1
-		browse_progress1 1 0 1 1
-		browse_progress2 2 0 1 1
-		browse_progress3 3 0 1 1
-	}
-}
-
-animations {
-	base {
-		body {
-			0.0 0 -4 0
-		}
-		
-		back_foot {
-			0.0 0 10 0
-		}
-		
-		front_foot {
-			0.0 0 10 0
-		}
-		
-		attach {
-		}
-	}
-
-	idle {
-		body {
-		}
-		
-		back_foot {
-			0.0 -7 0 0
-		}
-		
-		front_foot {
-			0.0  7 0 0
-		}
-		
-		attach {
-			0.0  0 0 0
-		}
-	}
-	
-	inair {
-		body {
-		}
-		
-		back_foot {
-			0.0 -3 0 -0.1
-		}
-		
-		front_foot {
-			0.0 3 0 -0.1
-		}
-		
-		attach {
-		}	
-	}
-
-	walk {
-		body {
-			0.0   0  0 0
-			0.2   0 -1 0
-			0.4   0  0 0
-			0.6   0  0 0
-			0.8   0 -1 0
-			1.0   0  0 0
-		}
-		
-		front_foot {
-			0.0   8  0 0
-			0.2  -8  0 0
-			0.4 -10 -4 0.2
-			0.6  -8 -8 0.3
-			0.8   4 -4 -0.2
-			1.0   8  0 0
-		}
-	
-		back_foot {
-			0.0 -10 -4 0.2
-			0.2  -8 -8 0.3
-			0.4  -4 -4 -0.2
-			0.6   0  0 0
-			0.8  -8  0 0
-			1.0 -10 -4 0.2
-		}
-		
-		attach {
-		}
-	}
-	
-	hammer_swing {
-		body {
-		}
-		
-		front_foot {
-		}
-	
-		back_foot {
-		}
-		
-		attach {
-			0.0 0 0 -0.10
-			0.3 0 0 0.25
-			0.4 0 0 0.30
-			0.5 0 0 0.25
-			1.0 0 0 -0.10
-		}
-	}	
-	ninja_swing {
-		body {
-		}
-		
-		front_foot {
-		}
-	
-		back_foot {
-		}
-		
-		attach {
-			0.0 0 0 -0.25
-			0.1 0 0 -0.05
-			0.15 0 0 0.35
-			0.42 0 0 0.4
-			0.5 0 0 0.35
-			1.0 0 0 -0.25
-		}
-	}	
-}
diff --git a/datasrc/datatypes.py b/datasrc/datatypes.py
index 9050b451..88678646 100644
--- a/datasrc/datatypes.py
+++ b/datasrc/datatypes.py
@@ -1,4 +1,164 @@
 
+	
+GlobalIdCounter = 0
+def GetID():
+	global GlobalIdCounter
+	GlobalIdCounter += 1
+	return GlobalIdCounter
+def GetUID():
+	return "x%d"%GetID()
+
+class BaseType:
+	def __init__(self, type_name):
+		self._type_name = type_name
+		self._target_name = "INVALID"
+		self._id = GetID() # this is used to remeber what order the members have in structures etc
+	
+	def Identifyer(self): return "x"+str(self._id)
+	def TargetName(self): return self._target_name
+	def TypeName(self): return self._type_name
+	def ID(self): return self._id;
+	
+	def EmitDeclaration(self, name):
+		return ["%s %s;"%(self.TypeName(), name)]
+	def EmitPreDefinition(self, target_name):
+		self._target_name = target_name
+		return []
+	def EmitDefinition(self, name):
+		return []
+
+class MemberType:
+	def __init__(self, name, var):
+		self.name = name
+		self.var = var
+		
+class Struct(BaseType):
+	def __init__(self, type_name):
+		BaseType.__init__(self, type_name)
+	def Members(self):
+		def sorter(a,b):
+			return a.var.ID()-b.var.ID()
+		m = []
+		for name in self.__dict__:
+			if name[0] == "_":
+				continue
+			m += [MemberType(name, self.__dict__[name])]
+		try:
+			m.sort(sorter)
+		except:
+			for v in m:
+				print v.name, v.var
+			sys.exit(-1)
+		return m
+		
+	def EmitTypeDeclaration(self, name):
+		lines = []
+		lines += ["struct " + self.TypeName()]
+		lines += ["{"]
+		for member in self.Members():
+			lines += ["\t"+l for l in member.var.EmitDeclaration(member.name)]
+		lines += ["};"]
+		return lines
+
+	def EmitPreDefinition(self, target_name):
+		BaseType.EmitPreDefinition(self, target_name)
+		lines = []
+		for member in self.Members():
+			lines += member.var.EmitPreDefinition(target_name+"."+member.name)
+		return lines
+	def EmitDefinition(self, name):
+		lines = ["/* %s */ {" % self.TargetName()]
+		for member in self.Members():
+			lines += ["\t" + " ".join(member.var.EmitDefinition("")) + ","]
+		lines += ["}"]
+		return lines
+		
+class Array(BaseType):
+	def __init__(self, type):
+		BaseType.__init__(self, type.TypeName())
+		self.type = type
+		self.items = []
+	def Add(self, instance):
+		if instance.TypeName() != self.type.TypeName():
+			error("bah")
+		self.items += [instance]
+	def EmitDeclaration(self, name):
+		return ["int num_%s;"%(name),
+			"%s *%s;"%(self.TypeName(), name)]
+	def EmitPreDefinition(self, target_name):
+		BaseType.EmitPreDefinition(self, target_name)
+
+		lines = []
+		i = 0
+		for item in self.items:
+			lines += item.EmitPreDefinition("%s[%d]"%(self.Identifyer(), i))
+			i += 1
+			
+		lines += ["static %s %s[] = {"%(self.TypeName(), self.Identifyer())]
+		for item in self.items:
+			itemlines = item.EmitDefinition("")
+			lines += ["\t" + " ".join(itemlines).replace("\t", " ") + ","]
+		lines += ["};"]
+		return lines
+	def EmitDefinition(self, name):
+		return [str(len(self.items))+","+self.Identifyer()]
+
+# Basic Types
+
+class Int(BaseType):
+	def __init__(self, value):
+		BaseType.__init__(self, "int")
+		self.value = value
+	def Set(self, value):
+		self.value = value
+	def EmitDefinition(self, name):
+		return ["%d"%self.value]
+		#return ["%d /* %s */"%(self.value, self._target_name)]
+		
+class Float(BaseType):
+	def __init__(self, value):
+		BaseType.__init__(self, "float")
+		self.value = value
+	def Set(self, value):
+		self.value = value
+	def EmitDefinition(self, name):
+		return ["%f"%self.value]
+		#return ["%d /* %s */"%(self.value, self._target_name)]
+		
+class String(BaseType):
+	def __init__(self, value):
+		BaseType.__init__(self, "const char*")
+		self.value = value
+	def Set(self, value):
+		self.value = value
+	def EmitDefinition(self, name):
+		return ['"'+self.value+'"']
+		
+class Pointer(BaseType):
+	def __init__(self, type, target):
+		BaseType.__init__(self, "%s*"%type().TypeName())
+		self.target = target
+	def Set(self, target):
+		self.target = target
+	def EmitDefinition(self, name):
+		return ["&"+self.target.TargetName()]
+
+# helper functions
+
+def EmitTypeDeclaration(root):
+	for l in root().EmitTypeDeclaration(""):
+		print l
+
+def EmitDefinition(root, name):
+	for l in root.EmitPreDefinition(name):
+		print l
+	print "%s %s = " % (root.TypeName(), name)
+	for l in root.EmitDefinition(name):
+		print l
+	print ";"
+
+# Network stuff after this
+
 class Object:
 	pass
 
@@ -52,6 +212,33 @@ class NetMessage(NetObject):
 		self.base_struct_name = "NETMSG_%s" % self.base.upper()
 		self.struct_name = "NETMSG_%s" % self.name.upper()
 		self.enum_name = "NETMSGTYPE_%s" % self.name.upper()
+	def emit_unpack(self):
+		lines = []
+		lines += ["static void *secure_unpack_%s()" % self.name]
+		lines += ["{"]
+		lines += ["\tstatic %s msg;" % self.struct_name]
+		for v in self.variables:
+			lines += ["\t"+line for line in v.emit_unpack()]
+		for v in self.variables:
+			lines += ["\t"+line for line in v.emit_unpack_check()]
+		lines += ["\treturn &msg;"]
+		lines += ["}"]
+		return lines
+	def emit_declaration(self):
+		extra = []
+		extra += ["\tvoid pack(int flags)"]
+		extra += ["\t{"]
+		extra += ["\t\tmsg_pack_start(%s, flags);"%self.enum_name]
+		for v in self.variables:
+			extra += ["\t\t"+line for line in v.emit_pack()]
+		extra += ["\t\tmsg_pack_end();"]
+		extra += ["\t}"]
+		
+		
+		lines = NetObject.emit_declaration(self)
+		lines = lines[:-1] + extra + lines[-1:]
+		return lines
+		
 
 class NetVariable:
 	def __init__(self, name):
@@ -60,14 +247,28 @@ class NetVariable:
 		return []
 	def emit_validate(self):
 		return []
+	def emit_pack(self):
+		return []
+	def emit_unpack(self):
+		return []
+	def emit_unpack_check(self):
+		return []
 
 class NetString(NetVariable):
 	def emit_declaration(self):
 		return ["const char *%s;"%self.name]
+	def emit_unpack(self):
+		return ["msg.%s = msg_unpack_string();" % self.name]
+	def emit_pack(self):
+		return ["msg_pack_string(%s, -1);" % self.name]
 
 class NetIntAny(NetVariable):
 	def emit_declaration(self):
 		return ["int %s;"%self.name]
+	def emit_unpack(self):
+		return ["msg.%s = msg_unpack_int();" % self.name]
+	def emit_pack(self):
+		return ["msg_pack_int(%s);" % self.name]
 
 class NetIntRange(NetIntAny):
 	def __init__(self, name, min, max):
@@ -75,7 +276,9 @@ class NetIntRange(NetIntAny):
 		self.min = str(min)
 		self.max = str(max)
 	def emit_validate(self):
-		return ["netobj_clamp_int(obj->%s, %s %s)"%(self.name, self.min, self.max)]
+		return ["netobj_clamp_int(\"%s\", obj->%s, %s, %s);"%(self.name,self.name, self.min, self.max)]
+	def emit_unpack_check(self):
+		return ["if(msg.%s < %s || msg.%s > %s) { msg_failed_on = \"%s\"; return 0; }" % (self.name, self.min, self.name, self.max, self.name)]
 
 class NetBool(NetIntRange):
 	def __init__(self, name):
diff --git a/datasrc/network.dts b/datasrc/network.dts
deleted file mode 100644
index ffa6dea4..00000000
--- a/datasrc/network.dts
+++ /dev/null
@@ -1,2 +0,0 @@
-const array:int sound = sounds.*
-const array:int weapon = weapons.*
diff --git a/datasrc/network.py b/datasrc/network.py
index 5029cbc1..6f03adb9 100644
--- a/datasrc/network.py
+++ b/datasrc/network.py
@@ -4,11 +4,33 @@ Emotes = ["NORMAL", "PAIN", "HAPPY", "SURPRISE", "ANGRY", "BLINK"]
 PlayerStates = ["UNKNOWN", "PLAYING", "IN_MENU", "CHATTING"]
 GameTypes = ["DM", "TDM", "CTF"]
 
-Enums = [Enum("GAMETYPE", GameTypes), Enum("PLAYERSTATE", PlayerStates), Enum("EMOTE", Emotes)]
+Emoticons = [str(x) for x in xrange(1,16)]
+
+Powerups = ["ARMOR", "HEALTH", "WEAPON", "NINJA"]
+
+RawHeader = '''
+enum
+{
+	INPUT_STATE_MASK=0x2f,
+};
+'''
+
+RawSource = '''
+#include <engine/e_common_interface.h>
+#include "g_protocol.h"
+'''
+
+Enums = [
+	Enum("GAMETYPE", GameTypes),
+	Enum("PLAYERSTATE", PlayerStates),
+	Enum("EMOTE", Emotes),
+	Enum("POWERUP", Powerups),
+	Enum("EMOTICON", Emoticons)
+]
 
 Objects = [
 
-	NetObject("PlayerInput", [
+	NetObject("Player_Input", [
 		NetIntAny("direction"),
 		NetIntAny("target_x"),
 		NetIntAny("target_y"),
@@ -77,7 +99,7 @@ Objects = [
 		NetIntAny("teamscore_blue"),
 	]),
 
-	NetObject("PlayerCore", [
+	NetObject("Player_Core", [
 		NetIntAny("x"),
 		NetIntAny("y"),
 		NetIntAny("vx"),
@@ -96,7 +118,18 @@ Objects = [
 		NetIntAny("hook_dy"),
 	]),
 
-	NetObject("PlayerCharacter:PlayerCore", [
+	NetObject("Player_Character:Player_Core", [
+		NetIntRange("player_state", 0, 'NUM_PLAYERSTATES-1'),
+		NetIntRange("wanted_direction", -1, 1),
+		NetIntRange("health", 0, 10),
+		NetIntRange("armor", 0, 10),
+		NetIntRange("ammocount", 0, 10),
+		NetIntRange("weapon", 0, 'NUM_WEAPONS-1'),
+		NetIntRange("emote", 0, len(Emotes)),
+		NetIntRange("attacktick", 0, 'max_int'),
+	]),
+	
+	NetObject("Player_Info", [
 		NetIntRange("local", 0, 1),
 		NetIntRange("cid", 0, 'MAX_CLIENTS-1'),
 		NetIntRange("team", -1, 1),
@@ -108,26 +141,30 @@ Objects = [
 	
 	## Events
 	
-	NetEvent("CommonEvent", [
+	NetEvent("Common", [
 		NetIntAny("x"),
 		NetIntAny("y"),
 	]),
 	
 
-	NetEvent("Explosion:CommonEvent", []),
-	NetEvent("Spawn:CommonEvent", []),
-	NetEvent("Death:CommonEvent", []),
-	NetEvent("AirJump:CommonEvent", []),
+	NetEvent("Explosion:Common", []),
+	NetEvent("Spawn:Common", []),
+	
+	NetEvent("Death:Common", [
+		NetIntRange("cid", 0, 'MAX_CLIENTS-1'),
+	]),
+	
+	NetEvent("AirJump:Common", []),
 
-	NetEvent("SoundGlobal:CommonEvent", [
+	NetEvent("SoundGlobal:Common", [
 		NetIntRange("soundid", 0, 'NUM_SOUNDS-1'),
 	]),
 
-	NetEvent("SoundWorld:CommonEvent", [
+	NetEvent("SoundWorld:Common", [
 		NetIntRange("soundid", 0, 'NUM_SOUNDS-1'),
 	]),
 
-	NetEvent("DamageInd:CommonEvent", [
+	NetEvent("DamageInd:Common", [
 		NetIntAny("angle"),
 	]),
 ]
diff --git a/datasrc/server.dts b/datasrc/server.dts
deleted file mode 100644
index aa3e12fd..00000000
--- a/datasrc/server.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-const array:int sound = sounds.*
-const array:int weapon = weapons.*
-const array:int powerup = powerups.*
-
-struct weapon {
-	int firedelay = firedelay@1
-	int meleedamage = meleedamage@1
-	int meleereach = meleereach@1
-	int ammoregentime = ammoregentime@1
-	int maxammo = maxammo@1
-	int duration = duration@1
-	int movetime = movetime@1
-	int velocity = velocity@1
-}
-
-struct powerupinf {
-	int amount = amount@1
-	int respawntime = respawntime@1
-	int startspawntime = startspawntime@1
-}
-
-struct data_container {
-	array:weapon weapons = weapons.*
-	array:powerupinf powerupinfo = powerups.*
-}
diff --git a/datasrc/teewars.dsd b/datasrc/teewars.dsd
deleted file mode 100644
index a95b960c..00000000
--- a/datasrc/teewars.dsd
+++ /dev/null
@@ -1,24 +0,0 @@
-tag:images {
-	ident:name * {
-		tag:filename string:filename
-	}
-}
-
-tag:sounds {
-	ident:name * {
-		tag:filename string:path
-	}
-}
-
-tag:weapons {
-	ident:name * {
-		tag:sprite_gun ptr:sprite
-		tag:sprite_cursor ptr:sprite
-	}
-}
-
-tag:sprites {
-	ident:name ptr:image int:gridx int:gridy * {
-		ident:name int:x int:y int:w int:h *
-	}
-}