commit bafd8e0ecf89e0958ebf1ee36025e3575deed630 Author: _bryan Date: Mon Jan 16 22:00:58 2023 +0100 first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..282320c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +raw/ \ No newline at end of file diff --git a/assets/master.fgd b/assets/master.fgd new file mode 100644 index 0000000..34525c3 --- /dev/null +++ b/assets/master.fgd @@ -0,0 +1,589 @@ +// +// Quake game definition file (.fgd) +// for Worldcraft 1.6 and above +// +// written by autolycus / autolycus@planetquake.com +// email me with improvements and suggestions +// + +// Modified by CZG : grawert@online.no : http://www.planetquake.com/greyvoid/ +// further modified by various authors + +// +// worldspawn +// + +@SolidClass = worldspawn : "World entity" +[ + message(string) : "Text on entering the world" + worldtype(choices) : "Ambience" : 0 = + [ + 0 : "Medieval" + 1 : "Metal (runic)" + 2 : "Base" + ] + sounds(integer) : "CD track to play" : 0 + light(integer) : "Ambient light" + _sunlight(integer) : "Sunlight" + _sun_mangle(string) : "Sun mangle (Yaw pitch roll)" +] + +// +// base marker definitions +// + +@baseclass = Angle [ angle(integer) : "Direction" ] + +@baseclass = Appearflags [ + spawnflags(Flags) = + [ + 256 : "Not on Easy" : 0 + 512 : "Not on Normal" : 0 + 1024 : "Not on Hard" : 0 + 2048 : "Not in Deathmatch" : 0 + ] +] + +@baseclass = Targetname [ targetname(target_source) : "Name" ] +@baseclass = Target [ + target(target_destination) : "Target" + killtarget(target_destination) : "Killtarget" +] + + + +// +// player starts, deathmatch, coop, teleport +// + +@baseclass base(Appearflags) size(-16 -16 -24, 16 16 32) + color(0 255 0) model({ "path": ":progs/player.mdl" }) = PlayerClass [] + +@PointClass base(PlayerClass) = info_player_start : "Player 1 start" [] +@PointClass base(PlayerClass) = info_player_coop : "Player cooperative start" [] +@PointClass base(PlayerClass) = info_player_start2 : "Player episode return point" [] +@PointClass base(PlayerClass) = info_player_deathmatch : "Deathmatch start" [] +@PointClass base(PlayerClass) = testplayerstart : "Testing player start" [] +@PointClass size(-32 -32 0, 32 32 64) base(PlayerClass, Targetname) = info_teleport_destination : "Teleporter destination" [] +@PointClass color(200 150 150) = info_null : "info_null (spotlight target)" +[ + targetname(target_source) : "Name" +] + +@PointClass base(Appearflags, Target, Targetname) color(200 150 150) = info_notnull : "Wildcard entity" // I love you +[ + use(string) : "self.use" + think(string) : "self.think" + nextthink(integer) : "nextthink" + noise(string) : "noise" + touch(string) : "self.touch" +] +@PointClass base(Appearflags) = info_intermission : "Intermission camera" +[ + mangle(string) : "Camera angle (Pitch Yaw Roll)" +] + +// +// items +// +@baseclass base(Appearflags, Target, Targetname) = Item +[ + message(string) : "Message" + target(string) : "Target" + killtarget(string) : "Killtarget" + delay(integer) : "Delay" +] +@baseclass size(0 0 0, 32 32 56) color(80 0 200) base(Item) = Ammo +[ + spawnflags(flags) = + [ + 1 : "Large box" : 0 + ] +] + +@PointClass + base(Ammo) + model( + {{ + spawnflags & 1 -> ":maps/b_batt1.bsp", + ":maps/b_batt0.bsp" + }} + ) = + item_cells : "Thunderbolt ammo" [] + +@PointClass + base(Ammo) + model( + {{ + spawnflags & 1 -> ":maps/b_rock1.bsp", + ":maps/b_rock0.bsp" + }} + ) = + item_rockets : "Rockets" [] + +@PointClass + base(Ammo) + model( + {{ + spawnflags & 1 -> ":maps/b_shell1.bsp", + ":maps/b_shell0.bsp" + }} + ) = item_shells : "Shells" [] + +@PointClass + base(Ammo) + model( + {{ + spawnflags & 1 -> ":maps/b_nail1.bsp", + ":maps/b_nail0.bsp" + }} + ) = item_spikes : "Nailgun/Perforator ammo" [] + +@PointClass + size(0 0 0, 32 32 56) + base(Appearflags) + model( + {{ + spawnflags & 2 -> ":maps/b_bh100.bsp", + spawnflags & 1 -> ":maps/b_bh10.bsp", + ":maps/b_bh25.bsp" + }} + ) = + item_health : "Health pack" +[ + spawnflags(flags) = + [ + 1 : "Rotten" : 0 + 2 : "Megahealth" : 0 + ] +] + +@PointClass size(-16 -16 -24, 16 16 32) base(Item, Appearflags) model({ "path": ":progs/suit.mdl" }) = + item_artifact_envirosuit : "Environmental protection suit" [] +@PointClass size(-16 -16 -24, 16 16 32) base(Item, Appearflags) model({ "path": ":progs/quaddama.mdl" }) = + item_artifact_super_damage : "Quad damage" [] +@PointClass size(-16 -16 -24, 16 16 32) base(Item, Appearflags) model({ "path": ":progs/invulner.mdl" }) = + item_artifact_invulnerability : "Pentagram of Protection" [] +@PointClass size(-16 -16 -24, 16 16 32) base(Item, Appearflags) model({ "path": ":progs/invisibl.mdl" }) = + item_artifact_invisibility : "Ring of Shadows" [] + +@PointClass size(-16 -16 0, 16 16 56) base(Item, Appearflags) model({ "path": ":progs/armor.mdl", "skin": 2 }) = + item_armorInv : "Red armor (200%)" [] +@PointClass size(-16 -16 0, 16 16 56) base(Item, Appearflags) model({ "path": ":progs/armor.mdl", "skin": 1 }) = + item_armor2 : "Yellow armor (150%)" [] +@PointClass size(-16 -16 0, 16 16 56) base(Item, Appearflags) model({ "path": ":progs/armor.mdl" }) = + item_armor1 : "Green armor (100%)" [] +@PointClass size(-16 -16 -24, 16 16 32) base(Item, Appearflags) model({ "path": ":progs/w_s_key.mdl" }) = + item_key1 : "Silver key" [] +@PointClass size(-16 -16 -24, 16 16 32) base(Item, Appearflags) model({ "path": ":progs/w_g_key.mdl" }) = + item_key2 : "Gold key" [] +@PointClass size(-16 -16 -24, 16 16 32) base(Item, Appearflags) model({ "path": ":progs/end1.mdl" }) = + item_sigil : "Sigil" +[ + spawnflags(Flags) = + [ + 1 : "Episode 1" : 1 + 2 : "Episode 2" : 0 + 4 : "Episode 3" : 0 + 8 : "Episode 4" : 0 + ] +] + +// +// weapons +// + +@baseclass size(-16 -16 0, 16 16 56) color(0 0 200) base(Item, Appearflags) = Weapon [] + +@PointClass base(Weapon) model({ "path": ":progs/g_shot.mdl" }) = weapon_supershotgun : "Double-barrelled shotgun" [] +@PointClass base(Weapon) model({ "path": ":progs/g_nail.mdl" }) = weapon_nailgun : "Nailgun" [] +@PointClass base(Weapon) model({ "path": ":progs/g_nail2.mdl" }) = weapon_supernailgun : "Super nailgun" [] +@PointClass base(Weapon) model({ "path": ":progs/g_rock.mdl" }) = weapon_grenadelauncher : "Grenade launcher" [] +@PointClass base(Weapon) model({ "path": ":progs/g_rock2.mdl" }) = weapon_rocketlauncher : "Rocket launcher" [] +@PointClass base(Weapon) model({ "path": ":progs/g_light.mdl" }) = weapon_lightning : "Thunderbolt" [] + +// +// monsters +// + +@baseclass base(Angle, Appearflags, Target, Targetname) color(220 0 0) = Monster +[ + spawnflags(Flags) = + [ + 1 : "Ambush" : 0 + ] +] + +@PointClass base(Monster) size(-16 -16 -24, 16 16 40) model({ "path": ":progs/soldier.mdl" }) = monster_army : "Grunt" [] +@PointClass base(Monster) size(-32 -32 -24, 32 32 40) model({ "path": ":progs/dog.mdl" }) = monster_dog : "Nasty Doggie" [] +@PointClass base(Monster) size(-32 -32 -24, 32 32 64) model({ "path": ":progs/ogre.mdl" }) = monster_ogre : "Ogre" [] +@PointClass base(Monster) size(-32 -32 -24, 32 32 64) model({ "path": ":progs/ogre.mdl" }) = monster_ogre_marksman : "Ogre marksman" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 40) model({ "path": ":progs/knight.mdl" }) = monster_knight : "Knight" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 40) model({ "path": ":progs/hknight.mdl" }) = monster_hell_knight : "Hell knight" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 40) model({ "path": ":progs/wizard.mdl" }) = monster_wizard : "Scrag" [] +@PointClass base(Monster) size(-32 -32 -24, 32 32 64) model({ "path": ":progs/demon.mdl" }) = monster_demon1 : "Fiend" [] +@PointClass base(Monster) size(-32 -32 -24, 32 32 64) model({ "path": ":progs/shambler.mdl" }) = monster_shambler : "Shambler" [] +@PointClass base(Monster) size(-128 -128 -24, 128 128 256) model({ "path": ":progs/boss.mdl" }) = monster_boss : "Chthon" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 40) model({ "path": ":progs/enforcer.mdl" }) = monster_enforcer : "Enforcer" [] +@PointClass base(Monster) size(-32 -32 -24, 32 32 64) model({ "path": ":progs/shalrath.mdl" }) = monster_shalrath : "Vore" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 24) model({ "path": ":progs/tarbaby.mdl" }) = monster_tarbaby : "Spawn" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 24) model({ "path": ":progs/fish.mdl" }) = monster_fish : "Rotfish" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 32) model({ "path": ":progs/oldone.mdl" }) = monster_oldone : "Shub-Niggurath" [] +@PointClass base(Monster) size(-16 -16 -24, 16 16 32) model({ "path": ":progs/zombie.mdl" }) = monster_zombie : "Zombie" +[ + spawnflags(Flags) = + [ + 1 : "Crucified" : 0 + 2 : "Ambush" : 0 + ] +] + +// +// lights +// + +@baseclass color(255 255 40) = Light [ + light(integer) : "Brightness" : 300 + wait(integer) : "Fade distance multiplier" : 1 + delay(choices) : "Attenuation" = + [ + 0 : "Linear falloff (Default)" + 1 : "Inverse distance falloff" + 2 : "Inverse distance squared" + 3 : "No falloff" + 4 : "Local minlight" + 5 : "Inverse distance squared B" + ] + mangle(string) : "Spotlight angle" + style(Choices) : "Appearance" : 0 = + [ + 0 : "Normal" + 10: "Fluorescent flicker" + 2 : "Slow, strong pulse" + 11: "Slow pulse, noblack" + 5 : "Gentle pulse" + 1 : "Flicker A" + 6 : "Flicker B" + 3 : "Candle A" + 7 : "Candle B" + 8 : "Candle C" + 4 : "Fast strobe" + 9 : "Slow strobe" + ] +] + +@PointClass size(-8 -8 -8, 8 8 8) base(Light, Target, Targetname) = + light : "Invisible light source" + [ + spawnflags(Flags) = [ 1 : "Start off" : 0 ] + ] +@PointClass size(-8 -8 -8, 8 8 8) base(Light, Target, Targetname) = + light_fluoro : "Fluorescent light" + [ + spawnflags(Flags) = [ 1 : "Start off" : 0 ] + ] +@PointClass size(-8 -8 -8, 8 8 8) base(Light, Target, Targetname) = + light_fluorospark : "Sparking fluorescent light" + [ + spawnflags(Flags) = [ 1 : "Start off" : 0 ] + ] +@PointClass size(-8 -8 -8, 8 8 8) base(Appearflags, Light, Target, Targetname) model({ "path": "progs/s_light.spr" }) = + light_globe : "Globe light" + [ + spawnflags(Flags) = [ 1 : "Start off" : 0 ] + ] +@PointClass size(-8 -8 -12, 8 8 20) base(Appearflags, Light, Target, Targetname) model({ "path": ":progs/flame2.mdl" }) = + light_flame_large_yellow : "Large yellow flame" + [ + spawnflags(Flags) = [ 1 : "Start off" : 0 ] + ] +@PointClass size(-4 -4 -12, 4 4 20) base(Appearflags, Light, Target, Targetname) model({ "path": ":progs/flame2.mdl" }) = + light_flame_small_yellow : "Small yellow flame" + [ + spawnflags(Flags) = [ 1 : "Start off" : 0 ] + ] +@PointClass size(-4 -4 -12, 4 4 20) base(Appearflags, Light, Target, Targetname) model({ "path": ":progs/flame2.mdl" }) = + light_flame_small_white : "Small white flame" + [ + spawnflags(Flags) = [ 1 : "Start off" : 0 ] + ] +@PointClass size(-4 -4 -12, 4 4 20) base(Appearflags, Light, Target, Targetname) model({ "path": ":progs/flame.mdl" }) = + light_torch_small_walltorch : "Small walltorch" [] + +// +// misc +// + +@SolidClass base(Appearflags) = func_illusionary : "Static nonsolid model" [] + +@PointClass base(Appearflags) color(0 150 220) model({ "path": ":progs/s_bubble.spr" }) = air_bubbles : "Air bubbles" [] +@PointClass base(Appearflags, Targetname) = + event_lightning : "Chthon's lightning" [] +@PointClass base(Appearflags) model({ "path": ":progs/lavaball.mdl" }) = misc_fireball : "Small fireball" + [ speed(integer) : "Speed" : 40 ] +@PointClass base(Appearflags) size(0 0 0, 32 32 64) model({ "path": ":maps/b_explob.bsp" }) = misc_explobox : "Large exploding container" [] +@PointClass base(Appearflags) size(0 0 0, 32 32 32) model({ "path": ":maps/b_exbox2.bsp" }) = misc_explobox2 : "Small exploding container" [] +@PointClass base(Appearflags) size(-8 -8 -8, 8 8 8) model({ "path": ":progs/teleport.mdl" }) = misc_teleporttrain : "Flying teleporter destination" +[ + target(string) : "First stop target" + targetname(target_source) : "Name" +] +@PointClass base(Appearflags, Targetname) color(220 150 150) = trap_spikeshooter : "Triggered shooter" +[ + spawnflags(Flags) = + [ + 1 : "Spike" : 0 + 2 : "Laser" : 0 + ] +] +@PointClass base(Appearflags) color(220 150 150) = trap_shooter : "Continuous shooter" +[ + nextthink(integer) : "Delay before first spike" + wait(integer) : "Delay between spikes" + spawnflags(Flags) = + [ + 1 : "Spike" : 0 + 2 : "Laser" : 0 + ] +] + +@SolidClass = func_group : "Group of brushes for in-editor use" [] +@SolidClass = func_detail : "Group of brushes for certain compilers" [] +@SolidClass = func_detail_illusionary : "func_detail variant with no collision (players / monsters / gunfire) and doesn't split world faces." [] +@SolidClass = func_detail_wall : "func_detail variant that doesn't split world faces." [] + +// +// ambient sounds +// + +@PointClass base(Appearflags) color(150 0 150) = ambient_drip : "Dripping sound" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_drone : "Engine/machinery sound" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_comp_hum : "Computer background sounds" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_flouro_buzz : "Fluorescent buzzing sound" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_light_buzz : "Buzzing sound from light" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_suck_wind : "Wind sound" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_swamp1 : "Frogs croaking" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_swamp2 : "Frogs croaking B" [] +@PointClass base(Appearflags) color(150 0 150) = ambient_thunder : "Thunder sound" [] + +// +// moving things +// + + +@SolidClass base(Angle, Appearflags, Targetname, Target) = func_door : "Basic door" +[ + speed(integer) : "Speed" : 100 + sounds(choices) : "Sound" : 0 = + [ + 0: "Silent" + 1: "Stone" + 2: "Machine" + 3: "Stone Chain" + 4: "Screechy Metal" + ] + wait(string) : "Wait before close" : "3" + lip(integer) : "Lip" : 8 + dmg(integer) : "Damage inflicted when blocked" : 2 + message(string) : "Message if touched" + health(integer) : "Health (shootable)" : 0 + spawnflags(flags) = + [ + 1 : "Starts Open" : 0 + 4 : "Don't link" : 0 + 8 : "Gold Key required" : 0 + 16: "Silver Key required" : 0 + 32: "Toggle" : 0 + ] +] + +@SolidClass base(Appearflags, Targetname, Target) = func_door_secret : "Secret door" +[ + angle(integer) : "Direction of second move" + t_width(integer) : "First move length" + t_length(integer) : "Second move length" + dmg(integer) : "Damage when blocked" : 2 + wait(string) : "Wait before close" : "2" + sounds(choices) : "Sounds" : 3 = + [ + 1: "Medieval" + 2: "Metal" + 3: "Base" + ] + message(string) : "Message" + spawnflags(flags) = + [ + 1 : "Open once" : 0 + 2 : "Move left first" : 0 + 4 : "Move down first" : 0 + 8 : "Not shootable" : 0 + 16 : "Always shootable" : 0 + ] +] + +@SolidClass base(Appearflags, Targetname) = func_wall : "Wall, starts animation when triggered (if supporting texture)" [] + + +@SolidClass base(Angle, Appearflags, Targetname) = func_button : "Button" +[ + speed(integer) : "Speed" : 40 + lip(integer) : "Lip" : 4 + target(target_source) : "Target" + health(integer) : "Health (shootable)" + sounds(choices) : "Sounds" = + [ + 0 : "Steam metal" + 1 : "Wooden clunk" + 2 : "Metallic clink" + 3 : "In-out" + ] + wait(string) : "Wait before reset" : "1" + delay(string) : "Delay before trigger" + message(string) : "Message" +] + +@SolidClass base(Appearflags, Targetname) = func_train : "Moving platform" +[ + sounds(choices) : "Sound" : 1 = + [ + 0: "Silent" + 1: "Ratchet Metal" + ] + speed(integer) : "Speed (units per second)" : 64 + target(target_source) : "Target to start at" + dmg(integer) : "Damage on block" : 2 +] + +@PointClass base(Appearflags, Targetname) size(16 16 16) color(0 255 255) = + path_corner : "Waypoint for platforms and monsters" +[ + target(target_source) : "Next target" + wait(integer) : "Wait" : 0 +] + +@SolidClass base(Appearflags, Targetname) = func_plat : "Elevator" +[ + spawnflags(Flags) = + [ + 1 : "Low trigger volume" : 0 + ] + speed(integer) : "Speed" : 150 + height(integer) : "Travel altitude (can be negative)" : 0 + sounds(choices) : "Sound" : 1 = + [ + 0: "None" + 1: "Base fast" + 2: "Chain Slow" + ] +] + +@SolidClass base(Appearflags) = func_episodegate : "Episode Gate" +[ + spawnflags(Flags) = + [ + 1 : "Episode 1" : 1 + 2 : "Episode 2" : 0 + 4 : "Episode 3" : 0 + 8 : "Episode 4" : 0 + ] +] + +@SolidClass base(Appearflags) = func_bossgate : "Boss gate" [] + +// +// triggers +// + +@baseclass base(Appearflags, Target, Targetname) = Trigger +[ + sounds(choices) : "Sound style" : 0 = + [ + 0 : "None" + 1 : "Secret sound" + 2 : "Beep beep" + 3 : "Large switch" + ] + delay(string) : "Delay before trigger" : "0" + message(string) : "Message" +] + +@SolidClass base(Trigger) = trigger_changelevel : "Trigger: Change level" +[ + map(string) : "Next map" + target(target_destination) : "Target" + spawnflags(flags) = + [ + 1: "No intermission" : 0 + ] +] + +@SolidClass base(Trigger) = trigger_once : "Trigger: Activate once" +[ + health(integer) : "Health (shootable)" + spawnflags(flags) = [ 1: "Not touchable" : 0 ] +] +@SolidClass base(Trigger) = trigger_multiple : "Trigger: Activate multiple" +[ + wait(string) : "Wait before reset" : "0.2" + health(integer) : "Health (shootable)" + spawnflags(flags) = [ 1: "Not touchable" : 0 ] +] +@SolidClass base(Trigger) = trigger_onlyregistered : "Trigger: Registered only" +[ + spawnflags(flags) = [ 1: "Not touchable" : 0 ] +] +@SolidClass base(Trigger) = trigger_secret : "Trigger: Secret" +[ + sounds(choices) : "Sound" : 1 = + [ + 1 : "Secret sound" + 2 : "Beep beep" + ] + spawnflags(flags) = [ 1: "Not touchable" : 0 ] +] + +@SolidClass base(Appearflags, Target, Targetname) = trigger_teleport : "Trigger: Teleporter" +[ + spawnflags(Flags) = + [ + 1 : "Player only" : 0 + 2 : "Silent" : 0 + ] +] + +@SolidClass base(Appearflags) = trigger_setskill : "Trigger: Set skill" +[ + message(choices) : "Skill to change to" : 1 = + [ + 0 : "Easy" + 1 : "Medium" + 2 : "Hard" + 3 : "Nightmare!" + ] +] +@PointClass base(Trigger) = trigger_relay : "Trigger: Relay" +[ +] +@SolidClass base(Angle, Appearflags, Targetname) = trigger_monsterjump : "Trigger: Monster jump" +[ + speed(integer) : "Jump Speed" : 200 + height(integer) : "Jump Height" : 200 +] +@PointClass base(Appearflags, Target, Targetname) = trigger_counter : "Trigger: Counter" +[ + spawnflags(flags) = [ 1: "No Message" : 0 ] + count(integer) : "Count before trigger" : 2 + delay (integer) : "Delay" + message(string) : "Message" +] +@SolidClass base(Angle, Appearflags, Targetname) = trigger_push : "Trigger: Push" +[ + spawnflags(flags) = [ 1: "Push once" : 0 ] + speed(integer) : "Speed" : 1000 +] +@SolidClass base(Appearflags, Targetname) = trigger_hurt : "Trigger: Hurt" +[ + dmg(integer) : "Damage per second" : 5 +] +@PointClass size(16 16 16) = misc_noisemaker : "Debug entity: continuously plays enforcer sounds" [] +@PointClass size(16 16 16) = viewthing : "Debug entity: fake player model" [] \ No newline at end of file diff --git a/assets/meshes/maps/autosave/test.1.map b/assets/meshes/maps/autosave/test.1.map new file mode 100644 index 0000000..f6e3c25 --- /dev/null +++ b/assets/meshes/maps/autosave/test.1.map @@ -0,0 +1,50 @@ +// Game: Generic +// Format: Standard +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures" +"_tb_def" "external:master.fgd" +"integer" "10" +"floating" "10.248" +"string" "sfdoijsdf" +// brush 0 +{ +( 0 0 16 ) ( 0 -128 16 ) ( 0 -128 -16 ) generic_tiles 0 0 45 1 1 +( 0 -128 16 ) ( 128 -128 16 ) ( 128 -128 -16 ) generic_tiles 0 0 45 1 1 +( 128 -128 -16 ) ( 128 0 -16 ) ( 0 0 -16 ) generic_tiles 0 0 45 1 1 +( 0 0 16 ) ( 128 0 16 ) ( 128 -128 16 ) generic_tiles 0 0 45 1 1 +( 128 0 -16 ) ( 128 0 16 ) ( 0 0 16 ) generic_tiles 0 0 45 1 1 +( 128 -128 16 ) ( 128 0 16 ) ( 128 0 -16 ) generic_tiles 0 0 45 1 1 +} +// brush 1 +{ +( -384 384 0 ) ( -384 384 64 ) ( -384 -64 0 ) generic_tiles 0 0 45 1 1 +( -384 384 64 ) ( -285.39994983020347 52.87499999999663 64 ) ( -384 -64 0 ) generic_tiles 35.14084 11.834999 45 1 1 +( -285.39994983020347 52.87499999999663 64 ) ( -184.606925748656 -41.49999999956605 64 ) ( -384 -64 0 ) generic_tiles 35.14084 11.834999 45 1 1 +( -184.606925748656 -41.49999999956605 64 ) ( 0 -64 64 ) ( -384 -64 0 ) generic_tiles 0 1.4594574 45 1 1 +( -384 -64 0 ) ( 0 -64 64 ) ( 0 -64 0 ) generic_tiles 0 0 45 1 1 +( 0 -64 0 ) ( 0 384 0 ) ( -384 384 0 ) generic_tiles 0 0 45 1 1 +( -384 384 64 ) ( 0 384 64 ) ( 0 -64 64 ) generic_tiles 0 0 45 1 1 +( 0 384 0 ) ( 0 384 64 ) ( -384 384 64 ) generic_tiles 0 0 45 1 1 +( 0 -64 64 ) ( 0 384 64 ) ( 0 384 0 ) generic_tiles 0 0 45 1 1 +} +} +// entity 1 +{ +"classname" "air_bubbles" +"origin" "-136 168 72" +} +// entity 2 +{ +"classname" "func_detail" +// brush 0 +{ +( 0 -128 0 ) ( 0 -127 0 ) ( 0 -128 1 ) generic_tiles 0 0 45 1 1 +( 0 -128 0 ) ( 0 -128 1 ) ( 1 -128 0 ) generic_tiles 0 0 45 1 1 +( 0 -128 0 ) ( 1 -128 0 ) ( 0 -127 0 ) generic_tiles 0 0 45 1 1 +( 64 0 64 ) ( 64 1 64 ) ( 65 0 64 ) generic_tiles 0 0 45 1 1 +( 64 0 64 ) ( 65 0 64 ) ( 64 0 65 ) generic_tiles 0 0 45 1 1 +( 64 0 64 ) ( 64 0 65 ) ( 64 1 64 ) generic_tiles 0 0 45 1 1 +} +} diff --git a/assets/meshes/maps/test.map b/assets/meshes/maps/test.map new file mode 100644 index 0000000..2076835 --- /dev/null +++ b/assets/meshes/maps/test.map @@ -0,0 +1,20 @@ +// Game: Generic +// Format: Standard +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures" +"_tb_def" "external:master.fgd" +"integer" "10" +"floating" "10.248" +"string" "sfdoijsdf" +// brush 0 +{ +( -64 160 0 ) ( -64 161 0 ) ( -64 160 1 ) __TB_empty 0 -16 0 1 1 +( -64 160 0 ) ( -64 160 1 ) ( -63 160 0 ) __TB_empty 0 -16 0 1 1 +( -64 160 0 ) ( -63 160 0 ) ( -64 161 0 ) __TB_empty 0 0 0 1 1 +( -32 192 16 ) ( -32 193 16 ) ( -31 192 16 ) __TB_empty 0 0 0 1 1 +( -32 192 16 ) ( -31 192 16 ) ( -32 192 17 ) __TB_empty 0 -16 0 1 1 +( -32 192 16 ) ( -32 192 17 ) ( -32 193 16 ) __TB_empty 0 -16 0 1 1 +} +} diff --git a/assets/models/arrangements/arrange1.glb b/assets/models/arrangements/arrange1.glb new file mode 100644 index 0000000..db60b6b Binary files /dev/null and b/assets/models/arrangements/arrange1.glb differ diff --git a/assets/models/missing.glb b/assets/models/missing.glb new file mode 100644 index 0000000..a9e749e Binary files /dev/null and b/assets/models/missing.glb differ diff --git a/assets/textures/generic_bricks.png b/assets/textures/generic_bricks.png new file mode 100644 index 0000000..b5a7728 Binary files /dev/null and b/assets/textures/generic_bricks.png differ diff --git a/assets/textures/generic_noise.png b/assets/textures/generic_noise.png new file mode 100644 index 0000000..0fb6d01 Binary files /dev/null and b/assets/textures/generic_noise.png differ diff --git a/assets/textures/generic_tiles.png b/assets/textures/generic_tiles.png new file mode 100644 index 0000000..fd476ae Binary files /dev/null and b/assets/textures/generic_tiles.png differ diff --git a/assets/textures/missing.png b/assets/textures/missing.png new file mode 100644 index 0000000..dc8573b Binary files /dev/null and b/assets/textures/missing.png differ diff --git a/source/__main__.py b/source/__main__.py new file mode 100644 index 0000000..f7cda49 --- /dev/null +++ b/source/__main__.py @@ -0,0 +1,55 @@ + +from direct.showbase.ShowBase import ShowBase +from panda3d.core import WindowProperties, GeomVertexArrayFormat, GeomVertexFormat, Geom, GeomVertexData, GeomVertexWriter, GeomTriangles, GeomNode +from panda3d.core import VirtualFileSystem +from panda3d.core import Vec3 + +from map.file import parse_map_file + + +class DungeonCell: + def __init__(self): + self.mesh = None + self.bounds = [None, None] + self.connections = [] + + def getBounds(self): + bmin, bmax = self.mesh.getTightBounds() + self.bounds = [bmin, bmax] + +class CellArrange1(DungeonCell): + def __init__(self): + DungeonCell.__init__(self) + self.mesh = loader.loadModel("/models/arrangements/arrange1.glb") + + self.connections = [ + Vec3(0, 5, 0), + Vec3(0, -5, 0), + Vec3(5, 0, 0), + Vec3(-5, 0, 0) + ] + self.getBounds() + +class Game(ShowBase): + def __init__(self): + ShowBase.__init__(self) + + vfs = VirtualFileSystem.getGlobalPtr() + vfs.mount('assets', '/', 0) + + tex_bricks = loader.loadTexture('/textures/generic_bricks.png') + tex_floor = loader.loadTexture('/textures/generic_tiles.png') + + + self.room = CellArrange1() + self.room.mesh.reparentTo(render) + self.room.mesh.find('**/A1.Walls').setTexture(tex_bricks, 1) + self.room.mesh.find('**/A1.Floor').setTexture(tex_floor, 1) + print(self.room.bounds) + + winprops = WindowProperties() + winprops.setSize(1600, 900) + self.win.requestProperties(winprops) + +game = Game() +game.run() \ No newline at end of file diff --git a/source/map/__init__.py b/source/map/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/source/map/csg.py b/source/map/csg.py new file mode 100644 index 0000000..1b323fd --- /dev/null +++ b/source/map/csg.py @@ -0,0 +1,11 @@ + + +from panda3d.core import Vec3 + + + + + +def convert_to_csg(mapfile): + + return \ No newline at end of file diff --git a/source/map/file.py b/source/map/file.py new file mode 100644 index 0000000..721f940 --- /dev/null +++ b/source/map/file.py @@ -0,0 +1,124 @@ + +from re import match as regexp +from enum import Enum +from panda3d.core import Vec3 + + +class MapFace: + def __init__(self): + self.v1 = Vec3() + self.v2 = Vec3() + self.v3 = Vec3() + self.tex = '' + self.offset = Vec3() + self.scale = Vec3() + self.angle = 0.0 + self.normal = Vec3() + +class MapBrush: + def __init__(self): + self.faces = [] + +class MapEntity: + def __init__(self): + self.classname = '' + self.attributes = {} + self.brushes = [] + +class MapFile: + def __init__(self, filepath, entities): + self.filepath = filepath + self.entities = entities + def entity_count(self): + return len(self.entities) + def brush_count(self): + total = 0 + for ent in self.entities: + total += len(ent.brushes) + return total + def face_count(self): + total = 0 + for ent in self.entities: + for brush in ent.brushes: + total += len(brush.faces) + return total + +class MapStack(Enum): + TOP = 0 + ENTITY = 1 + BRUSH = 2 + + + +def parse_map_file(filepath): + entities = [] + with open(filepath, 'r') as mapfile: + current_stack = MapStack.TOP + current_entity = None + current_brush = None + + for mapline in mapfile: + if mapline[:2] == '//': + continue + + if current_stack == MapStack.TOP and mapline[:1] == '{': + current_stack = MapStack.ENTITY + current_entity = MapEntity() + entities.append(current_entity) + + elif current_stack == MapStack.ENTITY and mapline[:1] == '}': + current_stack = MapStack.TOP + current_entity = None + + elif current_stack == MapStack.ENTITY and mapline[:1] == '{': + current_stack = MapStack.BRUSH + current_brush = MapBrush() + current_entity.brushes.append(current_brush) + + elif current_stack == MapStack.BRUSH and mapline[:1] == '}': + current_stack = MapStack.ENTITY + current_brush = None + + elif current_stack == MapStack.ENTITY and mapline[:1] == '"': + result = regexp('^"(.+)" "(.+)"$', mapline) + current_entity.attributes[result.group(1)] = result.group(2) + + elif current_stack == MapStack.BRUSH and mapline[:1] == '(': + result = regexp("^(\\(.+\\)) (.+)", mapline) + coordinates = result.group(1) + texture = result.group(2).split(' ') + + as_num = lambda v: float(v) + verts = regexp("^\\( (.+?) \\) \\( (.+?) \\) \\( (.+?) \\)$", coordinates) + verts1 = map(as_num, verts.group(1).split(' ')) + verts2 = map(as_num, verts.group(2).split(' ')) + verts3 = map(as_num, verts.group(3).split(' ')) + + current_face = MapFace() + current_face.v1 = Vec3(tuple(verts1)) + current_face.v2 = Vec3(tuple(verts2)) + current_face.v3 = Vec3(tuple(verts3)) + current_face.tex = texture[0] + current_face.offset = Vec3(float(texture[1]), float(texture[2]), 0) + current_face.angle = float(texture[3]) + current_face.scale = Vec3(float(texture[4]), float(texture[5]), 0) + current_brush.faces.append(current_face) + + edge_a = current_face.v2 - current_face.v1 + edge_b = current_face.v3 - current_face.v1 + current_face.normal = edge_b.cross(edge_a).normalized() + return MapFile(filepath, entities) + +''' +mapfile = parse_map_file("C:\\Users\\Bryan\\Documents\\MBH\\assets\\meshes\\maps\\test.map") +print(mapfile.entity_count()) +print(mapfile.brush_count()) +print(mapfile.face_count()) +''' + + + + + + +