/* ============================================================================ Half-Life world emulation 0.1alpha To provide a working half-life world for deathmatch and for user created maps to take advantage of. Created by Kryten (kryten@inside3d.com) If you add to this file place your name, email and the functions you create at the bottom. Top reserved for the creators functions. If you make changes to the creators functions then you should comment out the original code. To use in your modification: -place included files in your mod folder -add an entry for each of the files to the bottom of the progs.src, but place the halflife.qh directly after the defs.qc! -seach this file for -bot-, if you use the frikbot you should enable that code -delete func_wall and func_illusionary from the misc.qc -delete trigger_push and trigger_push_touch from the triggers.qc -add this to the world.qc after InitBodyQue (); if (self.WaveHeight) cvar_set ("r_waterripple ", self.WaveHeight); =============================================================================== Copyright (C) 2000 Kryten. may contain code Copyright (C) 1996 Id Software, Inc. may contain code Copyright (C) 2000 Valve LLC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =============================================================================== */ /* =============================================================================== Half-Life emulated world objects Walls, Illusionary Walls, Togglable Walls, Ladders, Breakable Walls, Triggered Explosions, Generic Ambient sounds, Wall Health charger, Water, Pushable Walls, Converors =============================================================================== */ void () BSP_Basic = { self.angles = '0 0 0'; self.movetype = MOVETYPE_PUSH; self.solid = SOLID_BSP; self.alpha = (self.renderamt / -255) + 1; if (self.alpha) self.fullbright = TRUE; // in HL transparent models are fullbright self.colormod_x = (self.rendercolor_x / -255) + 1; self.colormod_y = (self.rendercolor_y / -255) + 1; self.colormod_z = (self.rendercolor_z / -255) + 1; setmodel (self, self.model); setorigin (self, self.origin); setsize (self, self.mins, self.maxs); }; // ============================================================================ /*QUAKED func_wall (0 .5 .8) ? This is just a solid wall if not inhibitted */ void() func_wall = { BSP_Basic (); self.use = func_wall_use; }; /*QUAKED func_illusionary (0 .5 .8) ? A simple entity that looks solid but lets you walk through it. */ void() func_illusionary = { BSP_Basic (); self.movetype = MOVETYPE_NONE; self.solid = SOLID_NOT; // makestatic (self); }; void() func_wall_toggle_use = { if (self.effects & EF_NODRAW) { self.movetype = MOVETYPE_PUSH; self.solid = SOLID_BSP; self.effects = self.effects - EF_NODRAW; } else { self.movetype = MOVETYPE_NONE; self.solid = SOLID_NOT; self.effects = self.effects | EF_NODRAW; } }; void() func_wall_toggle = { BSP_Basic (); self.use = func_wall_toggle_use; self.message = self.model; if (self.spawnflags & 1) { self.movetype = MOVETYPE_NONE; self.solid = SOLID_NOT; self.modelindex = 0; self.model = ""; } }; // ============================================================================ void() trigger_push_touch = { if (other.classname == "grenade") other.velocity = self.speed * self.movedir * 10; else if (other.health > 0 && other.classname != "player") other.velocity = self.speed * self.movedir * 10; else if (other.health > 0 && other.classname == "player") // bots? { if (self.spawnflags & 1) { // Instant trigger, just transfer velocity and remove other.velocity = self.speed * self.movedir * 10; if (other.velocity_z > 0 ) other.flags = other.flags - other.flags & FL_ONGROUND; } else { // Push field, transfer to base velocity other.velocity = self.speed * self.movedir * 10; // local vector vecPush; // vecPush = (self.speed * self.movedir * 10); // if (other.flags & FL_BASEVELOCITY) // vecPush = vecPush + other.basevelocity; // other.basevelocity = vecPush; // other.flags = other.flags | FL_BASEVELOCITY; } } if (self.spawnflags & 1) remove(self); // other.velocity = self.speed * self.movedir * 10; // if (other.classname == "player") // { // if (other.fly_sound < time) /// { // other.fly_sound = time + 1.5; // sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM); // } // } // } }; void () trigger_push_toggle = { if (self.solid == SOLID_NOT) self.solid = SOLID_TRIGGER; else self.solid = SOLID_NOT; }; /*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE Pushes the player */ void() trigger_push = { eprint (self); if (self.angles == '0 0 0') self.angles_y = 360; InitTrigger (); if (self.spawnflags & 2) self.solid = SOLID_NOT; self.use = trigger_push_toggle; precache_sound ("ambience/windfly.wav"); self.touch = trigger_push_touch; if (!self.speed) self.speed = 1000; }; // ============================================================================ void() func_ladder_touch = { if (other.classname != "player") return; // if (!other.ishuman) // -bot- // return; other.gravity = 0.001; other.flags = other.flags | FL_ONLADDER; }; void() func_ladder = { InitTrigger (); // link to world self.touch = func_ladder_touch; }; // ============================================================================ void() func_breakable_break = { self.takedamage = DAMAGE_NO; SUB_UseTargets (); self.weapon = self.explodemagnitude; if (!self.weapon) self.weapon = self.iMagnitude; if (self.weapon) { self.origin = 0.5 * (self.absmin + self.absmax); // for bmodel center T_RadiusDamage (self, world, self.weapon, world); WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_EXPLOSION); WriteCoord (MSG_BROADCAST, self.origin_x); WriteCoord (MSG_BROADCAST, self.origin_y); WriteCoord (MSG_BROADCAST, self.origin_z); BecomeExplosion (); } else remove (self); }; void() func_breakable_touch = { if (other.classname != "player") return; local float flDamage; if (self.spawnflags & 2) {// can be broken when run into flDamage = vlen(other.velocity) * 0.01; if (flDamage >= self.health) { self.touch = SUB_Null; T_Damage(self, other, other, flDamage); // do a little damage to player if we broke glass or computer T_Damage (other, self, self, flDamage/4); } } if (self.spawnflags & 4 && (other.absmin_z > (self.absmax_z - 2))) // room for error {// can be broken when stood upon self.think = func_breakable_break; self.nextthink = time + self.delay; } }; void() func_breakable = { BSP_Basic (); self.th_die = func_breakable_break; if (self.spawnflags & 2 || self.spawnflags & 4) self.touch = func_breakable_touch; if (self.spawnflags & 1) self.use = func_breakable_break; else self.takedamage = DAMAGE_YES; }; void() env_explosion = { self.use = func_breakable_break; }; // ============================================================================ void() ambient_generic_play = { if (self.spawnflags & 32) sound (self, CHAN_AUTO, self.message, self.health, self.weapon); else ambientsound (self.origin, self.message, self.health, self.weapon); }; void() ambient_generic = { precache_sound (self.message); self.health = self.health / 10; // sound volume, 1-10, changed to 0.1 - 1 if (self.health > 1) self.health = 1; if (self.spawnflags & 1) self.weapon = ATTN_NONE; else self.weapon = ATTN_STATIC; if (self.spawnflags & 16) self.use = ambient_generic_play; else ambient_generic_play (); }; // ============================================================================ void() func_healthcharger_restore = { self.health = 50; self.frame = 1 - self.frame; // change to alternate textures sound(self, CHAN_ITEM, "items/itembk2.wav", 1, ATTN_NORM); }; void() func_healthcharger_heal = { if ((self.health < 1) || (other.health >= 100) || (other.classname != "player")) return; if (self.waitmin > time) return; other.health = other.health + 1; self.health = self.health - 1; self.waitmin = time + 0.25; sound(other, CHAN_ITEM, "items/r_item1.wav", 0.5, ATTN_NORM); if ((self.health < 1) && (deathmatch || coop)) { self.frame = 1 - self.frame; // change to alternate textures self.nextthink = time + self.dmdelay; self.think = func_healthcharger_restore; } }; void() func_healthcharger = { precache_sound ("items/r_item1.wav"); precache_sound ("items/itembk2.wav"); self.angles = '0 0 0'; self.movetype = MOVETYPE_NONE; self.solid = SOLID_TRIGGER; self.colormod_x = (self.rendercolor_x / -255) + 1; self.colormod_y = (self.rendercolor_y / -255) + 1; self.colormod_z = (self.rendercolor_z / -255) + 1; self.alpha = (self.renderamt / -255) + 1; if (self.alpha) self.fullbright = TRUE; // in HL transparent models are fullbright setmodel (self, self.model); self.health = 50; if (!self.dmdelay) self.dmdelay = 300; self.touch = func_healthcharger_heal; }; // ============================================================================ void () func_water_touch = { if (other.classname != "player") return; // if (!other.ishuman) // -bot- // return; other.waterlevel = 1; if ((other.origin_z + (other.mins_z + other.maxs_z)*0.5) <= self.absmax_z) other.waterlevel = 2; if (other.origin_z + other.view_ofs_z <= self.absmax_z) other.waterlevel = 3; other.gravity = 0.001; other.flags = other.flags | FL_WATERHACK; }; void () func_water = { self.angles = '0 0 0'; self.movetype = MOVETYPE_NONE; self.solid = SOLID_TRIGGER; self.alpha = (self.renderamt / -255) + 1; self.colormod_x = (self.rendercolor_x / -255) + 1; self.colormod_y = (self.rendercolor_y / -255) + 1; self.colormod_z = (self.rendercolor_z / -255) + 1; if (self.alpha) self.fullbright = TRUE; // in HL transparent models are fullbright setmodel (self, self.model); self.touch = func_water_touch; self.watertype = self.skin; }; // ============================================================================ void () func_pushable_push = { if (other.classname != "player") return; if (other.flags & FL_ONGROUND && other.groundentity && other.groundentity == self) return; // Is entity standing on this pushable ? if (!(other.flags & FL_ONGROUND)) // Don't push away from jumping/falling players return; self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity_x = self.velocity_x + other.velocity_x * 0.25; self.velocity_y = self.velocity_y + other.velocity_y * 0.25; }; void() func_pushable = { // not working for some reason if (self.spawnflags & 128) func_breakable (); else BSP_Basic (); self.origin_z = self.origin_z + 1; }; // ============================================================================ void() func_conveyor_use = { self.speed = self.speed * -1; }; void() func_conveyor = { // uses angles and speed if (self.angles) SetMovedir (); BSP_Basic (); if (self.spawnflags & 2) { self.movetype = MOVETYPE_NONE; self.solid = SOLID_NOT; } if (!self.speed) self.speed = 100; self.use = func_conveyor_use; }; // ============================================================================ /* =============================================================================== Half-Life emulated world objects Health, Ammo, Weapons does not work most of the time because they fall out of the level. =============================================================================== */ /* void() item_healthkit = { self.origin = self.origin + '-16 -16 15'; item_health(); }; void() ammo_357 = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_spikes"; item_spikes(); }; void() ammo_9mmAR = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_spikes"; item_spikes(); }; void() ammo_9mmbox = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_spikes"; item_spikes(); }; void() ammo_9mmclip = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_spikes"; item_spikes(); }; void() ammo_ARgrenades = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_rockets"; item_rockets(); }; void() ammo_buckshot = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_shells"; item_shells(); }; void() ammo_crossbow = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_spikes"; item_spikes(); }; void() ammo_gaussclip = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_cells"; item_cells(); }; void() ammo_glockclip = { self.origin = self.origin + '-16 -16 15'; remove (self); }; void() ammo_mp5grenades = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_rockets"; item_rockets(); }; void() ammo_rpgclip = { self.origin = self.origin + '-16 -16 15'; self.classname = "item_rockets"; item_rockets(); }; void() weapon_357 = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_nailgun"; weapon_nailgun(); }; void() weapon_9mmAR = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_supernailgun"; weapon_supernailgun(); }; void() weapon_9mmhandgun = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_nailgun"; weapon_nailgun(); }; void() weapon_crossbow = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_nailgun"; weapon_nailgun(); }; void() weapon_crowbar = { self.origin = self.origin + '0 0 15'; remove (self); }; void() weapon_egon = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_lightning"; weapon_lightning(); }; void() weapon_gauss = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_lightning"; weapon_lightning(); }; void() weapon_handgrenade = { self.origin = self.origin + '0 0 15'; remove (self); }; void() weapon_hornetgun = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_supernailgun"; weapon_supernailgun(); }; void() weapon_python = { self.origin = self.origin + '0 0 15'; remove (self); }; void() weapon_rpg = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_rocketlauncher"; weapon_rocketlauncher(); }; void() weapon_satchel = { self.origin = self.origin + '0 0 15'; remove (self); }; void() weapon_shotgun = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_supershotgun"; weapon_supershotgun(); }; void() weapon_snark = { self.origin = self.origin + '0 0 15'; remove (self); }; void() weapon_tripmine = { self.origin = self.origin + '0 0 15'; self.classname = "weapon_grenadelauncher"; weapon_grenadelauncher(); }; */ /* =============================================================================== Half-Life emulated world objects =============================================================================== */ void() path_track = {}; void() info_target = {}; void() light_environment = {}; void() light_spot = {}; void() info_node = // -bot- { // make_waypoint (self.origin); // remove (self); }; /* =============================================================================== Half-Life emulated world objects do nothings misc types and functions that cause errors for not being there thanx to DP developer settings these are not needed, but here for faster loading and other engines (and to give me a list of thing i might want to add) not all entities, but most from the deathmatch maps =============================================================================== */ /* .string texture; .float roomtype, radius, pitch, hinttype, activity, startspeed, unlocked_sound, locked_sound; .float locked_sentence, unlocked_sentence, volstart, fadein, fadeout, movesnd, stopsnd, spinup; .float chaptertitle, newunit, gametitle, startdark, MaxRange, MaxDelay, landmark, cspinup; .float lfomodvol, lfomodpitch, lforate, lfotype, spindown, pitchstart, preset, material, spawnobject; .float explosion, healthvalue, gibmodel, scale, shootsounds, shootmodel, m_flGibLife; .float m_flVariance, m_flVelocity, m_iGibs, triggerstate, gib_mma, gib3, gib2, gib1, gib_mm, damagetype; .float monstercount, monstertype, m_imaxlivechildren, secret_gate_sw, circk_1; .float cricka, sequence, bullet_damage, maxRange, minRange, barrelz, barrely, bullet, spriteflash; .float firespread, persistence, firerate, spritescale, barrel, pitchtolerance, pitchrange, pitchrate; .float yawtolerance, yawrange, yawrate, bullet_damage, framerate; void() env_glow = {remove(self);}; void() env_sprite = {remove(self);}; void() env_shooter = {remove(self);}; void() env_sound = {remove(self);}; // special sound rendering (eg large room echo) void() env_spark = {remove(self);}; void() func_monsterclip = {remove(self);}; void() func_recharge = {remove(self);}; void() func_tracktrain = {remove(self);}; void() func_tank = {remove(self);}; void() func_tankcontrols = {remove(self);}; void() infodecal = {remove(self);}; void() info_landmark = {remove(self);}; void() item_antidote = {remove(self);}; void() item_battery = {remove(self);}; void() item_longjump = {remove(self);}; void() monstermaker = {remove(self);}; void() monster_tripmine = {remove(self);}; void() multi_manager = {remove(self);}; void() scripted_sequence = {remove(self);}; void() trigger_auto = {remove(self);}; */